Handler源码的简单解析

来源:互联网 发布:淘宝网二手车 编辑:程序博客网 时间:2024/05/10 00:50

源码路径:framework/base/core/java/android/os/*

关于Handler涉及的主要类有Handler, Looper, Message, MessageQueue

     ①.Looper类采用单例设计模式,不可以使用new对象的方式,首先来说Looper中第一个重要的方法prepare()/prepareMainLooper() ,作用是来进行初始化,获取Looper对象。在主线程中调用prepareMainLooper() 方法,子线程中调用prepare(),其实最终调用的都是prepare(boolean quitAllowed) 方法,只不过主线程中参数传的为false,设置Looper不允许退出。在它的私有构造方法内有这么一条语句: mQueue = new MessageQueue(quitAllowed),所以在Looper实例化的时候,同时也实例化了一个消息队列。
      Looper中第二个重要的loop()方法,是他能够循环处理消息队列中消息的核心。在for死循环中不断的进行获取message,然后处理message,最后回收message操作,
在消息队列没有message时会出现阻塞,直到有message进入队列时继续进行(具体实现方式在MessageQueue类中,原理类似于操作系统中生产者消费者模型)。
msg.target的返回值是一个Handler,在Handler发送Message时默认会将它本身传给msg.target;dispathMessage是Handler中的一个方法,所有的具体操作是在Handler实现的子类中进行。

public static void loop() {
    final MessageQueue queue = me.mQueue;
    for (;;) {
        Message msg = queue.next(); // might block
        msg.target.dispatchMessage(msg);
        msg.recycleUnchecked();
    }
}

     总的来看,Looper是对循环处理消息队列里消息的一个封装,通过调用prepare()/prepareMainLooper() 和loop() 进行一个初始化,并提供两个方法myLoop(),myQueue()分别来获取创建的Looper对象和MessageQueue对象,在接下来创建Handler的时候我们须要用到它来获取Looper。

     ②.Handler类内部包含了一系列的构造方法,发送和获得消息的方法。首先我们来了解它是如何发送消息的。根据需求内部提供了几种不同的方法,主要分为发送普通消息,空消息和一个post()方法,具体的调用顺序如下:

sendMessage(Message msg)  -> sendMessageDelayed(msg,0) -> sendMessageAtTime(msg,SystemClock.uptimeMillis()+delayMillis) -> enqueueMessage(queue,msg,uptimeMillis);
sendEmptyMessage(int what)  -> sendEmptyMessageDelayed(what,0)(内部调用Message.obtain()获得一个Message,并将what添加到message.what中) -> sendMessageDelayed(msg,0)
post(Runnable r) -> sendMessageDelayed(getPostMessage(r),0)(其中getPostMessage(r)方法内会获得一个Message对象,将r赋给msg.r,并将这个对象作为返回值返回)
 在发送空消息时,在sendEmptyMessageDelayed(what,0)方法内其实又封装一个消息,最终都是调用enqueueMessage()方法将消息加入到消息队列,而消息队列的获取就是在其构造方法中通过调用
Looper.mLooper()获得mLooper对象,得到mLooper对象后通过mLooper.mQueue获得其消息队列的。
     Hander有几种不同的构造方法

Handler() -> Handler(Callback callback,boolean async)
Handler(Callback callback) -> Handler(Callback callback,boolean async)
Handler(Looper looper) -> Handler(Looper looper,Callback callback,boolean async)
Handler(Looper looper,Callback callback) -> Handler(Looper looper,Callback callback,boolean async)
Handler(boolean async) -> Handler(Callback callback,boolean async)
     通过构造函数可以看出,构造函数的区别在于Looper,Callback和async。如果不设置Looer参数,默认调用当前线程的looper; 如果不设置async默认为false,表示操作是同步执行;Callback是Handler类内部的一个接口,如果实现接口中的方法在消息队列中处理消息时会调用该接口中的方法,前面讲到在Handler发送Message时默认会将它本身传给msg.target,在处理消息时会调用dispathMessage()方法,它的具体实现如下
public void dispatchMessage(Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}
     从方法中可以看出,该方法首先调用msg.r实现的接口中的方法,也就是实现Runnable接口的子类的run()方法;
     如果没有实现该接口则去调用实现Handler类内部Callback接口的handleMessage(msg)方法;
     再如果前面接口都没有实现,最后才会去调用本类中的handleMessage(msg)方法,但是这个方法内部没有任何操作,须要我们自己去从写该方法。

总的来说Handler的作用就是对消息发送和消息的处理进行一个封装,并提供了三种方式让我们进行消息的处理。

0 0
原创粉丝点击