【Android】安卓开发之通过本地广播实现子线程和UI线程的通信

在做一个demo的时候,需要实现一个效果:当用户进行一些耗时操作的时候,显示一个进度条对话框,避免用户产生程序没反应的体验。而耗时操作一般都是在子线程中进行,而且如果耗时操作在子线程调用的外部类当中,那我们要如何让子线程将消息通知给UI线程,让UI线程及时的显示和收回进度条对话框呢?方法还是有的,比如说使用本地广播。

一、在子线程调用的外部类里,进行本地广播发送设置:

public class SendPostRequest {
    //-----------------------------声明一个本地广播管理器-------------------------------------------
    private LocalBroadcastManager localBroadcastManager;
    //----------------------------------------------------------------------------------------------
    public String sendPostRequest(String url, String param,Context context) {
        //-------------------------获取本地广播管理器的实例-----------------------------------------
        localBroadcastManager = LocalBroadcastManager.getInstance(context);
        //------------------------------------------------------------------------------------------
        //-------------------------要发送的广播消息,使用intent作为载体-----------------------------
        Intent intentEN = new Intent("LOCAL_BROADCAST_EN_PROGRESS_DIALOG");
        Intent intentDIS = new Intent("LOCAL_BROADCAST_DIS_PROGRESS_DIALOG");
        //------------------------------------------------------------------------------------------
        HttpURLConnection httpURLConnection = null;
        OutputStream out = null; //写
        InputStream in = null;   //读
        int responseCode = 0;    //远程主机响应的HTTP状态码
        String result = "";
        try {
            URL sendUrl = new URL(url);
            httpURLConnection = (HttpURLConnection) sendUrl.openConnection();
            //post方式请求
            httpURLConnection.setRequestMethod("POST");
            //设置头部信息
            httpURLConnection.setRequestProperty("headerdata", "ceshiyongde");
            //一定要设置 Content-Type 要不然服务端接收不到参数
            httpURLConnection.setRequestProperty("Content-Type", "application/Json; charset=UTF-8");
            //指示应用程序要将数据写入URL连接,其值默认为false(是否传参)
            httpURLConnection.setDoOutput(true);
            //httpURLConnection.setDoInput(true);
            httpURLConnection.setUseCaches(false);
            //--------------------发送弹出进度条对话框的本地广播------------------------------------
            localBroadcastManager.sendBroadcast(intentEN);
            //--------------------------------------------------------------------------------------
            httpURLConnection.setConnectTimeout(5000); //5秒连接超时
            httpURLConnection.setReadTimeout(3000);    //5秒读取超时
            //传入参数
            out = httpURLConnection.getOutputStream();
            out.write(param.getBytes());
            out.flush(); //清空缓冲区,发送数据
            out.close();
            responseCode = httpURLConnection.getResponseCode();
            //获取请求的资源
            BufferedReader br = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream(), "UTF-8"));
            result = br.readLine();
        } catch (Exception e) {
            e.printStackTrace();
        }
        Map<String, String> map = new Gson().fromJson(result, new TypeToken<Map<String, String>>() {
        }.getType());
        String msg = "";
        try{
            msg = map.get("msg");
        }catch (NullPointerException ne){
            Log.i("tag","网络连接异常");
        }
        //--------------------发送关闭进度条对话框的本地广播----------------------------------------
        localBroadcastManager.sendBroadcast(intentDIS);//后台不开的情况下,读取超时不起作用
        //------------------------------------------------------------------------------------------
        return msg;
    }
}

二、在UI线程里进行本地广播接收设置

public class RegisterPart2 extends BaseActivity {
    private final int PASSDIFF = 0;
    private final int LENLESS = 1;
    private final int REGSUCCESS = 2;
    private final int REGEXIST = 3;
    private final int REGFAIL = 4;
    private final int EN_PROCESSDIALOG = 5;
    private final int DIS_PROCESSDIALOG = 6;
    private String userName;
    private IntentFilter intentFilter_en;
    private IntentFilter intentFilter_dis;
    private LocalReceiver localReceiver;
    private LocalBroadcastManager lm;
    AlertDialog.Builder dialog;
    //对象的获得不能放在Handler里,不然会重复创建,然后指向的不是一个对象,导致进度条对话框无法关闭
    ProgressDialog pd;
    //--------------------------------------------定义一个Handler来处理消息-------------------------
    final Handler handler = new Handler() {
        @Override
        public void handleMessage(Message message) {
            switch (message.what) {
                case PASSDIFF:
                    dialog.setMessage("两次输入的密码不一致!");
                    dialog.setCancelable(false);
                    dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int which) {

                        }
                    });
                    dialog.show();
                    break;
                case LENLESS:
                    dialog.setMessage("密码长度不足8位!");
                    dialog.setCancelable(false);
                    dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int which) {

                        }
                    });
                    dialog.show();
                    break;
                case REGSUCCESS:
                    dialog.setMessage("注册成功!");
                    dialog.setCancelable(false);
                    dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int which) {
                            //注册成功则跳转到登陆页面,不成功不跳转
                            Intent intent = new Intent(RegisterPart2.this, Login.class);
                            startActivity(intent);
                            ActivityCollector.finishAll();
                        }
                    });
                    dialog.show();
                    break;
                case REGEXIST:
                    dialog.setMessage("注册的账户已经存在!");
                    dialog.setCancelable(false);
                    dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int which) {

                        }
                    });
                    dialog.show();
                    break;
                case REGFAIL:
                    dialog.setMessage(message.obj+" 一定出了什么问题。。。╮(╯▽╰)╭ ");
                    dialog.setCancelable(false);
                    dialog.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialogInterface, int which) {

                        }
                    });
                    dialog.show();
                    break;
                case EN_PROCESSDIALOG://显示进度条对话框
                    pd.setCancelable(true);
                    pd.setMessage("请稍候......");
                    pd.show();
                    break;
                case DIS_PROCESSDIALOG://关闭进度条对话框
                    pd.dismiss();
                    break;
                default:
                    break;
            }
        }
    };
    //----------------------------------------------------------------------------------------------
    @Override
    protected void onDestroy(){
        super.onDestroy();
        //---------------------------当活动被销毁时,注销本地广播接收器-----------------------------
        lm.unregisterReceiver(localReceiver);
        //------------------------------------------------------------------------------------------
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.new_register_part2);

        dialog = new AlertDialog.Builder(RegisterPart2.this);//对话框
        pd = new ProgressDialog(RegisterPart2.this);//获取进度条对话框的对象

        //---------------------------注册本地广播---------------------------------------------------
        intentFilter_en = new IntentFilter();
        intentFilter_dis = new IntentFilter();
        intentFilter_en.addAction("LOCAL_BROADCAST_EN_PROGRESS_DIALOG");
        intentFilter_dis.addAction("LOCAL_BROADCAST_DIS_PROGRESS_DIALOG");
        localReceiver = new LocalReceiver();//获取本地广播接收器的对象
        lm = LocalBroadcastManager.getInstance(this);//获取本地广播管理器的对象
        lm.registerReceiver(localReceiver,intentFilter_en);
        lm.registerReceiver(localReceiver,intentFilter_dis);
        //------------------------------------------------------------------------------------------
        
        //---------------------------给状态栏设置颜色-----------------------------------------------
        TextView textViewActionBar = (TextView) findViewById(R.id.actionBarId);
        setActionBarColor(textViewActionBar, getResources().getColor(R.color.theRed));
        //------------------------------------------------------------------------------------------
        //----------------------------使用Intent解析上一个活动传来的数据----------------------------
        Intent intent = getIntent();
        userName = intent.getStringExtra("userName");
        //------------------------------------------------------------------------------------------
        final EditText regUserName = (EditText) findViewById(R.id.regist2NameEditId);
        final EditText regPassword = (EditText) findViewById(R.id.regist2PasswordEditId);
        final EditText regConfirm = (EditText) findViewById(R.id.regist2ConfirmEditId);
        EditText regEmail = (EditText) findViewById(R.id.regist2EmailEditId);
        Button confirmButton = (Button) findViewById(R.id.regist2ConfirmBottonId);

        /**
         * 完成注册,销毁之前的注册活动,直接跳到登陆界面,且不可返回之前注册活动
         */
        confirmButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //----------------------------------收回软键盘--------------------------------------
                InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                if (imm != null) {
                    imm.hideSoftInputFromWindow(getWindow().getDecorView().getWindowToken(),0);
                }
                //----------------------------------------------------------------------------------
                //---------------------通过POST请求将用户名和密码发送给服务器-----------------------
                try {
                    //新建一个线程,通过Message消息通知Handle对UI进行更改,现在只能在UI线程里对UI组件进行更改。
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            String password = regPassword.getText().toString();
                            String confirmPassword = regConfirm.getText().toString();
                            Message message = new Message();
                            if (!(password.equals(confirmPassword))) {//如果输入的密码不一致
                                message.what = PASSDIFF;
                                handler.sendMessage(message);
                                return;
                            }
                            if (password.length() < 8) {//如果输入的密码长度小于8位
                                message.what = LENLESS;
                                handler.sendMessage(message);
                                return;
                            }
                            //下面三句话,将会把三个参数包装为{"para1":10,"para2":2,"opt":"div"}字段
                            CalBean tb = new CalBean(userName, password);
                            Gson gson = new Gson();
                            String datas = gson.toJson(tb);
                            String url = " http://10.10.120.43:8080/Register";
                            SendPostRequest sendPostRequest = new SendPostRequest();
                            String data = sendPostRequest.sendPostRequest(url,datas,RegisterPart2.this);
                            //根据返回来的数据进行判断是否注册成功
                            if (data.equals("注册成功")) {
                                message.what = REGSUCCESS;
                                handler.sendMessage(message);
                                return;
                            } else if (data.equals("账户已存在")) {
                                message.what = REGEXIST;
                                handler.sendMessage(message);
                                return;
                            } else {
                                message.what = REGFAIL;
                                message.obj = data.toString();
                                handler.sendMessage(message);
                                return;
                            }
                        }
                    }).start();
                } catch (Exception e) {
                    Log.i("ok", "there must be something wrong!");
                    return;
                }
                //----------------------------------------------------------------------------------
            }
        });
    }
    //------------------------------------重写本地广播接收器----------------------------------------
    class LocalReceiver extends BroadcastReceiver{
        @Override
        public void onReceive(Context context,Intent intent){
            switch (intent.getAction()){
                case "LOCAL_BROADCAST_EN_PROGRESS_DIALOG":
                    Message en_message = new Message();
                    en_message.what = EN_PROCESSDIALOG;
                    handler.sendMessage(en_message);
                    break;
                case "LOCAL_BROADCAST_DIS_PROGRESS_DIALOG":
                    Message dis_message = new Message();
                    dis_message.what = DIS_PROCESSDIALOG;
                    handler.sendMessage(dis_message);
                    break;
                default:break;
            }
        }
    }
    //----------------------------------------------------------------------------------------------
}

效果:




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值