Android要点提炼总结之消息机制

消息机制

1、作用:跨线程通信
2、场景:当子线程进行耗时操作以后需要更新UI时,通过Handler将有关的UI操作切换到主线程中执行

系统不建议在子线程访问UI的原因:
1、UI线程非安全,在多线程中并发访问可能会导致UI控件处于不可预期的状态。
2、如果加上锁的话,会导致UI控件变得复杂和低效。同时会阻塞某些进程的运行

关键要素:

  • Message(消息):需要被传递的消息,由MessageQueue统一列队,最终由Handler处理
  • MessageQueue(消息队列):存放Message,内部通过单链表的数据结构来维护消息列表,Message可能来自不同的Handler
  • Handler:负责Message的处理和发送,包含着Looper和MessageQueue
  • Looper(消息泵):通过Looper.loopa()不断的从MessageQueue中抽取Message,按分发机制将消息分发给目标处理者,可以有多个的Handler
  • Thread(线程):负责调度整个消息循环,即消息循环的执行场所

3、具体的实现方式

  • 在主线程实例化一个全局的Handler对象;
  • 在需要执行UI操作的子线程里实例化一个Message并填充必要数据,调用Handler.sendMessage(Message msg)方法发送出去;
  • 复写handleMessage()方法,对不同Message执行相关操作;
private Handler handler = new Handler(){
    @Override public void handleMessage(Message msg) {
      super.handleMessage(msg);
      switch (msg.what) {
        case xxx:
          ...
          updateUI();
          break;
      }
    }
  };

  ....

  private void threadMethod() {
    new Thread(){
      @Override public void run() {
        super.run();

        //创建Message的三种方法
        //1、Message msg = new Message(); 
        //2、Message msg2 = Message.obtain(); 
        //3、Message msg1 = handler1.obtainMessage(); 

        handler.sendMessage(msg);

      }
    }.start();
  }

上面的Message的创建有三种方法,最好使用第二种和第三种,这样做的好处是避免重复创建Message对象。具体详见:Message的创建方式:new Message和obtainMessage的区别

下面就是在子线程中创建使用Handler

class LooperThread extends Thread{

  private Handler handler;

  public void run(){
      Looper.prepare();//这里面就是ThreadLocal.set(Looper);

      handler = new Handler(){

       public void handleMessage(){
          // 处理消息
         }
      }
   }
}

从上面的两个例子,我们可以看到通过handler的sendMessage方法来发送消息,通过Looper.loop方法进行消息循环。同时子线程里面要new一个Handler的时候,就必须在前面加上Looper.prepare()方法。至于消息的处理是隐藏在Loop和MessageQueue中,我们接下来会一点点的深入分析。

注意:我们为什么在新的线程里面,首先要Looper.prepar,而在主线程里面不需要。这是因为,我们主线程在程序入口的main方法里面已经调用了Looper.prepar。


ThreadLocal类是用来提供线程内部的局部变量。这些变量在多线程的环境下访问(通过get或者set方法访问)时能保证各个线程里的变量相对独立于其他的线程变量。
这玩意并不是为了解决多线程的访问共享变量,而是为了每个线程创建一个单独的变量副本

4、源码的分析

先看看Handler机制简图吧,这个是引用别人的图片
这里写图片描述

具体的源码分析,可以参考博客Android的消息机制分析

参考文章:
深入剖析ThreadLocal
android的消息处理机制(图+源码分析)——Looper,Handler,Message
Android的消息机制分析

猜你喜欢

转载自blog.csdn.net/zhangyDD/article/details/82423788