Android消息机制之—Handler

 

1.2 Handler

 

       /frameworks/base/core/java/android/os/Handler.java

Handler扮演者向MQ上添加消息和处理消息的角色,它通知MQ它要执行一个任务(sendMessage),并且loop到自己的时候执行该任务,整个过程是异步的。

 

*A Handler allows you to send and process {@link Message} and Runnable
 * objects associated with a thread's {@link MessageQueue}.  Each Handler
 * instance is associated with a single thread and that thread's message
 * queue.  When you create a new Handler, it is bound to the thread 
 * message queue of the thread that is creating it -- from that point on,
 * it will deliver messages and runnables to that message queue and execute
 * them as they come out of the message queue.

一个Handler允许发送与一个线程相关的Message和Runnable对象。每个Handler实例,都会和一个线程相连。如果创建一个新的Handler,它就会和线程的消息队列相连。

 

小结:一个线程可以有多个Handler,但只能有一个Looper。

 

public Handler(Callback callback, boolean async) {

      if (FIND_POTENTIAL_LEAKS) {

          final Class<? extends Handler> klass = getClass();

          if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&

              (klass.getModifiers() & Modifier.STATIC) == 0) {

               Log.w(TAG, "The following Handler class should be static or leaks might occur: " +

               klass.getCanonicalName());

          }

     }

     mLooper = Looper.myLooper(); //默认关联当前线程的Looper

     //looper不能为空,即默认的构造方法只能在looper线程中使用

     if (mLooper == null) {

         throw new RuntimeException(

             "Can't create handler inside thread that has not called Looper.prepare()");

      }

     mQueue = mLooper.mQueue

//直接把关联looper的MQ作为自己的MQ,因此它的消息将发送到关联//looper的MQ上。

     mCallback = callback;

     mAsynchronous = async;

 }

 

以上就是讲Handler和Looper线程的绑定和联系,下面讲Handler的消息发送和消息处理。

       Handler发送消息:

public final boolean post(Runnable r){
    return  sendMessageDelayed(getPostMessage(r), 0);
}
 
private static Message getPostMessage(Runnable r) {
        Message m = Message.obtain();
        m.callback = r;
        return m;
    }
 
  private static Message getPostMessage(Runnable r, Object token) {
        Message m = Message.obtain();
        m.obj = token;
        m.callback = r;
        return m;
  }

发送Runnable对象,它的run方法将在handler关联的looper线程中执行。在Handler中封装成Message。

post(Runnable),

postAtTime(Runnable, long),

postDelayed(Runnable, long),

sendEmptyMessage(int),

sendMessage(Message),

sendMessageAtTime(Message, long)

sendMessageDelayed(Message, long)

 

以上这些方法都是向MQ上发送消息的,字面上可见发送的消息为Runnable对象和Message对象。在源码中我们发现,Runnable对象也被封装为了Message对象。

 

下面分析一下,SendMessage函数,有利于理解Handler的处理过程:

从基本的sendMessage()开始,发现sendMessage调用了sendMessageDelayed()。

   public final boolean sendMessage(Message msg){
        return sendMessageDelayed(msg, 0);
    }
 
    public final boolean sendEmptyMessage(int what){
        return sendEmptyMessageDelayed(what, 0);
    }

 

public final boolean sendEmptyMessageDelayed(int what, long delayMillis) {
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageDelayed(msg, delayMillis);
}

 

发现sendEmptyMessageDelayed()最后也调用了sendMessageDelayed().

public final boolean sendMessageDelayed(Message msg, long delayMillis){
     if (delayMillis < 0) {
          delayMillis = 0;
      }
      return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}

sendMessageDelayed()调用了sendMessageAtTime();

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
              this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }

在sendMessageAtTime中,调用了enqueueMessage();

  private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this//message的target指向处理它的handler
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
   }

到这消息添加到了MQ中,并且每个消息的target都指向能够处理该消息的handler。

 

在loop()方法中的关键代码:

msg.target.dispatchMessage(msg);

正常添加的消息为Message对象,而post发出的message,其callback为Runnable对象。

 

接下来Handler处理消息:

核心方法dispatchMessage();

public void dispatchMessage(Message msg) {
      if (msg.callback != null) {
//如果消息设置了callback则为runnable消息,处理callback。
           handleCallback(msg);
       } else {
    //如果handler本省设置了callback,执行callback
         if (mCallback != null) {
// 这种方法允许让activity等来实现Handler.Callback接口,避免了//自己编写handler重写handleMessage方法
             if (mCallback.handleMessage(msg)) {
                 return;
             }
          }
//没有callback,调用handler的钩子方法handleMessage
          handleMessage(msg);
       }
}

 

钩子函数由Handler的子类来实现。

/**   * Subclasses must implement this to receive messages.     */
    public void handleMessage(Message msg) {
   }

//处理runnable消息—直接运行run方法。

private static void handleCallback(Message message) {
       message.callback.run();
 }

对于开发者来说,只要实现handleMessage钩子函数和Runnable对象的run方法外,其他的都是透明的。

 

Handler的用处:

1.    可以在任意线程中发送消息,这些消息会发送到它关联的MQ上。

2.    Handler是在它关联的looper线程中处理消息的。

通过Looper,Handler和Message的方式就解决了在非主线程中更新UI的问题。Android的主线程(UI线程)也是一个looper线程。

 


 

更多相关文章

  1. Android事件处理分析+Android事件处理 +Android输入事件流程
  2. Android(安卓)UI Operation in Thread
  3. Android(安卓)网络(四) Retrofit学习笔记
  4. 基于MQTT实现Android消息推送(Push)(2)
  5. First day of android study
  6. Android之Handler用法总结
  7. Android(安卓)Handler机制
  8. android的第一天学习
  9. Android(2017-2018)BAT面试题整理(Android篇,含答案)

随机推荐

  1. android api 完整翻译之Application Fund
  2. Android(安卓)EditText 学习笔记
  3. Android(安卓)手势识别判断,GestureDetect
  4. 【Android(安卓)Api 翻译3】android api
  5. 2010年Android随想!
  6. Android——多线程
  7. 我对学习delphiTeacher的《delphi调用及
  8. Android中的动画详解系列【4】——Activi
  9. android:layout_gravity和android:gravit
  10. Android优缺点