Handler消息机制彻底解析Handler解析

Handler

Handler老是依附于建立时所在的线程,好比咱们的Handler是在主线程中建立的,而在子线程中又没法直接对UI进行操做,因而咱们就经过一系列的发送消息、入队、出队等环节,最后调用到了Handler的handleMessage()方法中,这时的handleMessage()方法已是在主线程中运行的,于是咱们固然能够在这里进行UI操做了。整个异步消息处理流程的示意图以下图所示:android

异步消息处理流程
异步消息处理流程

Handler

这即是咱们平时直接使用的主角。继承Handler
重写其handleMessage()
方法来处理消息,在须要的时候调用sendMessage()
来发消息,剩下的就不用管了。如今来看看“咱们不用管”的这部分都干了点啥。bash

构造方法

全部的构造方法最终会会调用两个实现,若是制定了Looper,则会调用三个参数的重载,不然会调用两个参数的重载。然后者则会调用Lopper.myLooper()
来获取looper。两个构造方法除了给mLooper
赋值外,还给mQueue
赋值为mLooper.mQueue
;给mCallback
赋值为指定的callback或null;给mAsynchronous
赋值为指定的boolean或false。 在两个参数的构造方法中,给上述四个成员赋值前有段if(FIND_POTENTIAL_LEAKS){}
包裹的代码段,该变量定义为private static final boolean FIND_POTENTIAL_LEAKS = false;
所以推断这部分是开发时调试用的,此处不作理会。微信

建立消息obtainMessage()

根据源码能够看出,全部该方法的重载都调用了Message.obtain()
对应的重载,能够看Message.obtain()的前因后果来了解,此处再也不赘述。须要注意的是,每一个重载都传入了this
参数并赋值给了message的target
。这里先记着就行,后面会介绍如何经过target
调用dispatchMessage()
处理消息。app

发送消息sendMessage()

全部的sendEmptyMessage()
重载与sendMessageXXX()
以及postXXX()
最终都会调用enqueueMessage()
方法,该方法则调用queue.enqueueMessage()
方法将消息添加到消息队列。关于消息队列如何管理消息能够看MessageQueue的队列管理一文。异步

移除消息removeMessage()

全部的removeMessages()
重载与removeCallbacks()
重载最终都是调用mQueue.removeMessages()
方法,即经过MessageQueue来实现该操做。详细分析能够看MessageQueue的队列管理一文。ide

处理消息dispatchMessage()

消息处理最开始被调用的不是handleXXX()
方法,而是dispatchMessage()
方法。该方法会根据消息是否有callback
来判断该交给handleCallback()
仍是handleMessage()
。前者直接调用参数中message
的message.calback.run()
解决问题,后者则是空方法体,须要咱们开发者本身重写。oop

Handler一些特色

  • handler能够分发Message对象和Runnable对象到主线程中, 每一个Handler实例,都会绑定到建立他的线程中(通常是位于主线程),它有两个做用:post

    • (1)安排消息或Runnable 在某个主线程中某个地方执行;
    • (2)安排一个动做在不一样的线程中执行。

Handler实例

  • 子类须要继承Hendler类,并重写handleMessage(Message msg) 方法, 用于接受线程数据。ui

  • 如下为一个实例,它实现的功能为:经过线程修改界面Button的内容this

    public class MyHandlerActivity extends Activity { 
      Button button; 
      MyHandler myHandler; 
    
      protected void onCreate(Bundle savedInstanceState) { 
          super。onCreate(savedInstanceState); 
          setContentView(R。layout。handlertest); 
    
          button = (Button) findViewById(R。id。button); 
          myHandler = new MyHandler(); 
          // 当建立一个新的Handler实例时, 它会绑定到当前线程和消息的队列中,开始分发数据 
          // Handler有两个做用, (1) : 定时执行Message和Runnalbe 对象 
          // (2): 让一个动做,在不一样的线程中执行。 
    
          // 它安排消息,用如下方法 
          // post(Runnable) 
          // postAtTime(Runnable,long) 
          // postDelayed(Runnable,long) 
          // sendEmptyMessage(int) 
          // sendMessage(Message); 
          // sendMessageAtTime(Message,long) 
          // sendMessageDelayed(Message,long) 
    
          // 以上方法以 post开头的容许你处理Runnable对象 
          //sendMessage()容许你处理Message对象(Message里能够包含数据,) 
    
          MyThread m = new MyThread(); 
          new Thread(m)。start(); 
      } 
    
      /** 
      * 接受消息,处理消息 ,此Handler会与当前主线程一块运行 
      * */ 
    
      class MyHandler extends Handler { 
          public MyHandler() { 
          } 
    
          public MyHandler(Looper L) { 
              super(L); 
          } 
    
          // 子类必须重写此方法,接受数据 
          @Override 
          public void handleMessage(Message msg) { 
              // TODO Auto-generated method stub 
              Log。d("MyHandler""handleMessage。。。。。。"); 
              super。handleMessage(msg); 
              // 此处能够更新UI 
              Bundle b = msg。getData(); 
              String color = b。getString("color"); 
              MyHandlerActivity。this。button。append(color); 
    
          } 
      } 
    
      class MyThread implements Runnable { 
          public void run() { 
    
              try { 
                  Thread。sleep(10000); 
              } catch (InterruptedException e) { 
                  // TODO Auto-generated catch block 
                  e。printStackTrace(); 
              } 
    
              Log。d("thread。。。。。。。""mThread。。。。。。。。"); 
              Message msg = new Message(); 
              Bundle b = new Bundle();// 存放数据 
              b。putString("color""个人"); 
              msg。setData(b); 
    
              MyHandlerActivity。this。myHandler。sendMessage(msg); // 向Handler发送消息,更新UI 
    
          } 
      } 
    }复制代码

    若是你觉
    得此文对您有所帮助,欢迎入群 QQ交流群 :232203809
    微信公众号:终端研发部

技术+职场
技术+职场
相关文章
相关标签/搜索