Handler,Looper消息机制原理

来源:互联网 发布:淘宝客技巧 编辑:程序博客网 时间:2024/05/22 10:12

Android应用程序消息处理机制三部分:消息循环,消息发送,消息处理

Looper:消息循环

当我们打开一个应用程序的时候,系统会默认帮我们创建一个主线程ActivityThread(这是一个受保护的类,可以直接打开sdk位置,找到该类),在main方法中已经帮我们实现Looper。所以我们不需要再次实现该方法,也可以实现消息的发送,处理。当我们创建一个线程时就需要实现Looper来实现消息的循环处理。
下面看一下Looper的创建过程:

  public static void prepare() {    //初始化    prepare(true);}private static void prepare(boolean quitAllowed) {    //通过该行代码表明:一个Thread只能有一个Looper    if (sThreadLocal.get() != null) {        throw new RuntimeException("Only one Looper may be created per thread");    }    sThreadLocal.set(new Looper(quitAllowed));}

通过以上可以看出调用Looper的prepare方法,会默认帮我创建一个Looper,值得注意的是该方法表明一个Thread智能有一个Looper。存储到ThreadLocal中。对于ThreadLocal这里不做讲解,有兴趣的可以自行去看。如果看过源码的话会发现Looper中还有一个方法 prepareMainLooper()

public static void prepareMainLooper() {    prepare(false);    synchronized (Looper.class) {        if (sMainLooper != null) {            throw new IllegalStateException("The main Looper has already been prepared.");        }        sMainLooper = myLooper();    }

该方法就是我们之前所说的ActivityThread创建默认Looper时所调用,Looper还为我们提供了getMainLooper方法用于在任何地方获取主线程Looper对象。

public static Looper getMainLooper() {    synchronized (Looper.class) {        return sMainLooper;    }}

接下来就是Looper中的消息循环方法loop,该方法是一个死循环,我们可以下看下源码:

//调用loop进入到消息循环public static void loop() {    //获取当前Looper对象    final Looper me = myLooper();    if (me == null) {        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");    }    //获取当前消息队列    final MessageQueue queue = me.mQueue;    //循环取出下一消息,调用diapatchMessage分发,直到target=null    for (;;) {        //next方法用于判断,线程是否进入等待状态:1没消息,2延迟,定时发送的消息。消息队列中消息按照时间顺序排列        Message msg = queue.next(); // might block        if (msg == null) {            // No message indicates that the message queue is quitting.            return;        }        try {            //分发消息            msg.target.dispatchMessage(msg);        } finally {            if (traceTag != 0) {                Trace.traceEnd(traceTag);            }        }    }}

这里只贴出部分需要的源码,透过源码看一看出,loop中通过消息队列的next方法循环取出消息,若有新消息,则调用msg.target.dispatchMessage(msg);进行分发处理,这里msg.target目标对象就是发送消息的Handler对象。若无消息则next进入阻塞,刚才说过loop是个死循环除非next方法为空,才会跳出循环。
Looper提供了quit和quitSafely方法退出Looper。不同之处在于quit直接退出Looper,quitSafely设置一个安全退出标记,待消息队列中已有消除处理完毕,才会退出Looper,此时next方法返回null。需要注意的时loop方法要放在最后执行,因为loop方法之后的内容不会立即执行,有兴趣的可以试一下。

Handler:消息发送,消息处理

Handler包含消息的发送和处理两种过程。

消息发送

Handler 可以通过Post和send方法进行发送消息,其中post内部也是通过send发送消息:

public final boolean sendMessage(Message msg)public final boolean sendEmptyMessage(int what)public final boolean sendEmptyMessageDelayed(int what, long delayMillis)public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis)

像MessageQueue中插入一消息通过enqueueMessage方法,MessageQueue的next方法就会返回一条信息给Looper对象,最终还是调用handler 的dispatchMessage方法。

消息处理

在这里就需要看一下上面所说的dispatchMessage方法,我们看一下源码:

 public void dispatchMessage(Message msg) {    if (msg.callback != null) {        handleCallback(msg);    } else {        if (mCallback != null) {            if (mCallback.handleMessage(msg)) {                return;            }        }        handleMessage(msg);    }}

Handler处理消息过程:先查看Message的Callback 方法是否为空,不为空则调用handleCallback方法直接处理消息,可以看出调用了Message内部进行处理。

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

Message的Callback 方法为空,那么就继续判断mCallback 是否为空 ,这里的mCallback 是Handler 中的一个接口:

 public interface Callback {    public boolean handleMessage(Message msg);}

通过Callback 可以使用该方式创建一个Handler对象,就是可以创建出Handler实例但并不需要派生出Handler的子类,

 public Handler(Callback callback) {    this(callback, false);}

继续讲解消息的处理,若mCallback不为空,则调用接口中的handleMessage方法直接处理,若返回false,则最终调用handleMessage处理。

再添加一点:一个Thread对应一个Looper,一个Looper对应一个消息队列。

结束语:这是我对Android中消息机制的一点理解。

原创粉丝点击