• Android消息传递 Handler 消息机制


    前言:

          无论是现在所做的项目还是以前的项目中,都会遇见线程之间通信、组件之间通信,目前统一采用EventBus来做处理,在总结学习EventBus之前,觉得还是需要学习总结一下最初的实现方式,也算是不忘初心吧,这也是今天来学习总结Handler消息机制的一个原因。

      消息传递相关文章地址:

    Handler机制产生背景

          一个Android应用程序被创建的时候都会创建一个UI主线程,但是有时我们会有一些比较耗时的操作,为了防止阻塞UI主线程,我们会将耗时的操作放到子线程中进行处理,处理完之后操作UI,但是Android不允许子线程操作UI,违背了Android单线程模型的原则(即 Android UI操作并不是线程安全的并且这些操作必须在UI线程中执行),所以Android通过Handler消息机制来实现线程之间的通讯。

    Handler机制主要角色

        Message:消息,其中包含了消息ID,消息处理对象以及处理的数据等,由MessageQueue统一列队,终由Handler处理。 

        Handler:处理者,负责Message的发送及处理。使用Handler时,需要实现handleMessage(Message msg)方法来对特定的Message进行处理,例如更新UI等。 

        MessageQueue:消息队列,用来存放Handler发送过来的消息,并按照FIFO规则执行。当然,存放Message并非实际意义的保存,而是将Message以链表的方式串联起来的,等待Looper的抽取。 

        Looper:消息泵,不断地从MessageQueue中抽取Message执行。因此,一个MessageQueue需要一个Looper。 

        Thread:线程,负责调度整个消息循环,即消息循环的执行场所。

    Handler机制主要运用

        1.)发送消息,在不同的线程间发送消息,使用的方法为sendXXX();
    sendEmptyMessage(int);//发送一个空的消息
    sendMessage(Message);//发送消息,消息中可以携带参数
    sendMessageAtTime(Message, long);//未来某一时间点发送消息
    sendMessageDelayed(Message, long);//延时Nms发送消息

     举例:

     主线程定义Handler

    复制代码
      Handler mHandler = new Handler() {
    
            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    case 0:
                        //完成主界面更新,拿到数据
                        String data = (String) msg.obj;
                        textView.setText(data);
                        break;
                    default:
                        break;
                }
            }
        };
    复制代码

    子线程发消息,通知Handler完成UI更新

    复制代码
        private void getDataFromNet() {
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    //耗时操作,完成之后发送消息给Handler,完成UI更新;
                    mHandler.sendEmptyMessage(0);
    
                    //需要数据传递,用下面方法;
                    Message msg = new Message();
                    msg.obj = "网络数据";//可以是基本类型,可以是对象,可以是List、map等;
                    mHandler.sendMessage(msg);
                }
    
            }).start();
        }
    复制代码
    2.)计划任务,在未来执行某任务,使用的方法为postXXX();
    post(Runnable);//提交计划任务马上执行
    postAtTime(Runnable, long);//提交计划任务在未来的时间点执行
    postDelayed(Runnable, long);//提交计划任务延时Nms执行

    示例:

    主线程定义Handler

      private Handler mHandler=new Handler();

    子线程提交任务更新UI

    复制代码
        private void getDataFromNet() {
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    //耗时操作,完成之后提交任务更新UI
                    final String data = "网络数据";
                    mHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(data);
                        }
                    });
                }
            }).start();
        }
    复制代码

    Handler机制扩展

        为了更加方便的使用Handler消息机制,Android也提供了几种扩展方式,内部实现都是基于Handler消息机制

      1.) Activity.runOnUiThread(Runnable)
    复制代码
        private void getDataFromNet() {
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    //耗时操作,完成之后提交任务更新UI
                    final String data = "网络数据";
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(data);
                        }
                    });
                }
            }).start();
        }
    复制代码
    2 .)View.post(Runnable)
    复制代码
       private void getDataFromNet() {
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    //耗时操作,完成之后提交任务更新UI
                    final String data = "网络数据";
                    textView.post(new Runnable() {
                        @Override
                        public void run() {
                            textView.setText(data);
                        }
                    });
                }
            }).start();
        }
    复制代码

    5.)使用AsyncTask代替Thread

    复制代码
        private void getDataFromNet() {
            MyTask task = new MyTask();
            task.execute();
        }
    
        private class MyTask extends AsyncTask {
    
            //后台线程执行时
            @Override
            protected Object doInBackground(Object... params) {
                ////耗时操作,
                String data = "网络数据";
                return data;
            }
    
            //后台线程执行结束后的操作,其中参数result为doInBackground返回的结果
            @Override
            protected void onPostExecute(Object result) {
                super.onPostExecute(result);
                textView.setText((String) result);
            }
        }
    复制代码

    小结:

        至此Handler消息简单的总结到此结束,更多内部具体实现可以参考

       1.http://www.cnblogs.com/angeldevil/p/3340644.html

       2.http://blog.csdn.net/fei0724/article/details/8664462

  • 相关阅读:
    Windows性能计数器应用
    Azure Oracle Linux VNC 配置
    Azure 配置管理系列 Oracle Linux (PART6)
    Azure 配置管理系列 Oracle Linux (PART5)
    Azure 配置管理系列 Oracle Linux (PART4)
    Azure 配置管理系列 Oracle Linux (PART3)
    Azure 配置管理系列 Oracle Linux (PART2)
    vagrant多节点配置
    docker基本操作
    LINUX开启允许对外访问的网络端口命令
  • 原文地址:https://www.cnblogs.com/endv/p/13393072.html
Copyright © 2020-2023  润新知