Android中Message的一辈子

初始化

1
2
3
Looper.prepare();
Handler mHandler = new Handler(Looper.myLooper());
Looper.loop();

Looper.prepare()源码:

1
2
3
4
5
6
private static void prepare(boolean quitAllowed) {
    if (sThreadLocal.get() != null) {
        throw new RuntimeException("Only one Looper may be created per thread");
    }
    sThreadLocal.set(new Looper(quitAllowed));
}

Looper的构造方法:

1
2
3
4
private Looper(boolean quitAllowed) {
    mQueue = new MessageQueue(quitAllowed);
    mThread = Thread.currentThread();
}

初始化阶段主要做了四件事:

  1. 依赖ThreadLocal给当前线程创建Looper的独立对象;
  2. 在Looper构造方法中创建MessageQueue;
  3. 创建Handler对象;
  4. 启动循环获取消息。

创建消息

1
2
3
4
5
6

//方式1:
Message.obtain();

//方式2:
mHandler.obtainMessage();

发送

1
2
3
4
5
//方式1:
mHandler.sendMessage(msg);

//方式2:
msg.sendToTarget();

最终调用MessageQueue.enqueueMessage(Message msg, long when)

所谓的发送消息,其实是干了3件事:

  1. 把消息的状态改为inUse;
  2. 重组MessageQueue中的mMessages链条,把新消息放在队首;
  3. 唤醒Looper所在线程,开始循环处理消息。

接收

Looper的looper方法中循环调用MessageQueue的next方法读取新的message,如果有新消息,就调用handler的dispatchMessage(msg),进而调用handleCallback()或者调用handleMessage方法。最后通过msg的msg.recycleUnchecked();完成消息的回收复用。

而此时,如果没有消息,或者下一个消息是延迟消息且还没到时间,looper会回调所有的idleHandler,然后通过linux的epoll机制进入休眠,降低cpu负载,直到调用Looper对象的quitSafely(),进一步调MessageQueue的quit()方法,更改mQuitting标记,使MessageQueue的next方法返回null,跳出Lopper的loop循环,释放了线程。

明天补一张生命周期时序图吧,今天先到这了