Handler、Message、Runnable之间的联系(一)

Handler分发消息机制

Handler类怎么发送消息到消息队列里暂且不管,今天先看Handler怎么处理消息。
Handler要处理消息首先会分发消息,即通过它的dispatchMessage(Message msg)方法,其源码如下:

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

先简单理一下这个方法包含的内容。

参数msg为被分发的Message对象。

方法结构体是一个逻辑判断,首先判断msg的callback(属于Runnable类)为不为空值。如果不为空值,则执行handlerCallback(msg)方法,这个方法实际上就是执行callback的run方法。如果callback为空值,则接着判断Handler的mCallback(Handler的一个内部接口类)为不为空值,如果mCallback不为空值,则由它的handleMessage方法处理msg再根据其返回值决定是否由Handler的handleMessage方法继续处理msg,如果mCallback为空值,则直接由Handler处理msg。

消息处理方式详解

Runnable处理

根据dispatchMessage的消息处理流程可以分几种情况简单应用。

当我们只需要开启一个子线程,处理一下UI事件的时候,我们可以直接使用Handler类的post(Runnable r)方法,其源码如下:

public final boolean post(Runnable r)  
{  
   return  sendMessageDelayed(getPostMessage(r), 0);  
} 

这个方法实际上是使用sendMessageDelayed方法发送消息,只不过延迟时间为0。再看一下getPostMessage(r)的源码:

private static Message getPostMessage(Runnable r) {  
    Message m = Message.obtain();  
    m.callback = r;  
    return m;  
}  

实际上就是实例化了一个Message对象,再初始化了callback对象而已。当Handler分发消息,即执行dispatchMessage方法的时候,由于msg的callback不为空值则会执行handleCallback方法,handleCallback的源码如下:

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

一目了然,这个方法最终还是执行的是callback的run方法。

同样是依靠callback处理消息,还可以用另外一种方式来实现,即直接实例一个Message对象,再初始化其callback对象。而初始化其callback对象,必须通过Message的静态方法obtain(Handler h, Runnable callback)初始化才行,其源码如下:

public static Message obtain(Handler h, Runnable callback) {  
    Message m = obtain();  
    m.target = h;  
    m.callback = callback;  

    return m;  
}  

在这个方法里初始化了一个Message对象,然后为它初始化了target和callback,target就是Handler对象。初始化完后接着发送消息,这里不需要重新new一个Handler对象,只需要使用Message的sendToTarget方法就行了,sendToTarget的源码如下:

public void sendToTarget() {  
    target.sendMessage(this);  
} 

就是使用刚才初始化的target发送消息。

想要获得Message的target和callback可以通过getTarge方法和getCallback方法。

Handler或其内部接口类处理

当需要根据 不同的消息来处理事件的时候,Runnable就不好用了,我们需要实现Handle的成员接口类Callback或者继承Handler来处理。
前面讲了,当Handler的mCallback对象不为空时,需要根据mCallback接口的handleMessage方法的返回值来决定是否继续由Handler处理消息。mCallback的是Callback类,源码如下:

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

它是个接口类,需要我们自己实现它的方法,我们自己决定handleMessage的返回值。当我们决定返回true的时候,就只有Callback处理消息;当我们决定返回false的时候,消息还会由Handler继续处理。

所以只有当各种条件都满足的时候,才会由Handler的handleMessage来处理Message。它的源码如下:

public void handleMessage(Message msg) {  
}  

不要怀疑你的眼睛,源码就是这样,这个方法什么都没做。

所以当我们需要用Handler的handleMessage来处理消息的时候,我们必须继承Handler类重写这个方法。

关于Handler、Meesage、Runnable之间的联系先就写这么多,下次有空接着学习。

PS:这篇博文是我从自己CSDN的博客手动copy过来的,其他的简直没法看,所以就弄了这一篇过来。