Handler Looper MessageQueue之Handler

1、Handler

Handler.java文件位于framework/base/core/java/android/os/Handler.java

1.1 创建handler

源码中提供了7种handler构造方法

public Handler()
public Handler(Callback callback)
public Handler(Looper looper) 
public Handler(Looper looper, Callback callback)
public Handler(boolean async)
public Handler(Callback callback, boolean async)
public Handler(Looper looper, Callback callback, boolean async)

参数说明:
looper 不能为空,若为空则取的当前线程的looperLooper.myLooper(),若为null会抛出RuntimeException。因为messagequeue需要从looper中获取; callback是handler message的回调接口,用于处理消息; async true表示是异步的。默认是同步。

handler的成员变量

final MessageQueue mQueue;      存储java层looper对象内部的MessageQueue
final Looper mLooper;           存储java层的looper对象
final Callback mCallback;       回调函数,处理消息
final boolean mAsynchronous;    同步标识
IMessenger mMessenger;          用于跨进程的消息发送

创建handler所作的工作是 把之前在本线程中创建的Looper和MessageQueue关联到handler的成员变量中。handler的构造函数中,若传入了looper则表示吧handler与传入的looper以及这个looper持有的MessageQueue关联起来。若是没有传入,则默认使用sThreadLocal中存储的looper对象(mLooper = Looper.myLooper())。

构造方法前段的判断是说,如果当前Handler的子类是一个匿名类(klass.isAnonymousClass)或者一个成员类(klass.isMemberClass)或者是一个局部类(isLocalClass),而且当前Handler不是静态的(Modifier.STATIC) == 0),则提示用户可能造成内存泄露。

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();
    if (mLooper == null) {
        throw new RuntimeException(
            "Can't create handler inside thread that has not called Looper.prepare()");
    }
    mQueue = mLooper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}

public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
}

1.2 handler发送消息

android中提供了两组方法发送消息post和sendMessage,post发送的是Runnable线程实现,sendMessage接收的是Message参数。post方法最终获取了一个Message对象,然后把Runnable传给了Message的callback,然后调用了sendMessage方法:

 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;
}  

handler的SendMessage 最终调用的是SendMessageAtTime,其中delayMillis表示要延迟多少时间执行(相对当前时间),uptimeMillis表示在何时处理该消息

public final boolean sendMessage(Message msg)
{
    return sendMessageDelayed(msg, 0);
}

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

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);
}

sendMessage方法最终调用了当前handler成员变量MessageQueueenqueueMessage,此部分的分析见 Handler Looper MessageQueue之MessageQueue

1.3 dispatchMessage

MessageQueue中,Message.target.dispatchMessage会最终调用到Handler的dispatchMessage,这里处理的是Java层发送过来的消息。这里做了三次匹配:

首先是判断Message创建的时候是否指定了回调msg.callback != null,若指定了,则会调用handlerCallback方法,这部分一般用来处理post(Runnable runnable)发送过来的消息,因为会默认指定回调为runnable。该方法最终调用的是回调的run方法,也就是启动该线程。

然后是判断handler创建的时候,是否指定了回调handler(Callback callback),这个callback会赋值给成员变量mCallback,若指定了,会调用该callback的handlerMessage方法,这个方法需要创建handler的时候自己实现接口。

最后,剩余的消息走系统默认的处理方法handlerMessage。默认的处理方法是空方法,也是需要子类类复写该方法。

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


private static void handleCallback(Message message) {
    message.callback.run();
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值