1.2 Handler机制
Handler源码分析
一、基础
1. Message: 消息实体
2. MessageQueue: 提供投递消息(MessageQueue#enqueueMessage), 和消费消息(MessageQueue#next)
3. Handler: 向MessageQueue发送消息(#sendMessage), 和处理相应的消息(#handleMessage)
4. Looper: 循环消息队列, 按分发机制讲消息分发给目标处理者
二、流程
1. Looper#prepare, 初始化Looper放到ThreadLocal
2. Looper#loop, 读取MessageQueue的消息, 把Message分发给相应的target, 把消息放回消息池, 以便复用
3. 消息分发机制, 当Message不为空, 调用Message#callback#run, 否则当Handler#mCallback不为空, 回调方法mCallback#handleMessage, 否则调用Handler#handleMessage
4. 消息发送, Handler#sendMessageDelayed -> Handler#sendMessageAtTime -> Message#queueMessage
5. MessageQueue#next, nativePollOnce是阻塞操作, 其中nextPollTimeoutMills代表下一个消息到来需要等待的时长, 当nativePollOnce返回时, next()从mMessage中提取一条消息
6. MessageQueue#enqueueMessage, 队头消息是最早触发的消息, 当有消息插入时, 会从队列头开始遍历, 直到找到消息合适插入位置, 确保消息的时间顺序
三、Handler(Native层)
1. MessageQueue初始化, 创建Looper -> 创建epoll注册wait管道, 将唤醒事件(mWakeEventFd)添加到epoll实例, epoll_create/epoll_ctl
2. nativePollOnce, MessageQueue#nativePollOnce -> Looper#pollOnce -> Looper#pollInner -> epoll_wait; 1. 调用epoll_wait阻塞方法, 用于等待事件发生或者超时, 2. epoll_wait返回: POOL_ERROR, 发生错误, 直接跳转到Done; POLL_TIMEOUT, 超时跳转到Done; 检测到管道有事件, (1)如果是管道读端产生事件, 则直接读取管道的数据, (2)如果是其它事件, 则处理request并生成response, push到response数组
3. nativeWait, 用于唤醒, 包括`enqueueMessage`和`quit`都会调用`nativeWake`, 向管道写入字符
4. 先处理Native Message, 再处理Native Request最后处理Java Message
1.2.1 Handler机制, Looper#loop()为什么不会卡死
真正会卡死主线程的操作是在回调方法onCreate/onStart/onResume等操作时间过长,会导致掉帧,甚至发生ANR,looper.loop本身不会导致应用卡死。looper.loop会消耗cpu, 但不会卡死, 另外它也不是无休止地循环, 而是有消息才会循环
1.2.2 Handler退出
调用Looper#quit - > MessageQueeu#quit, 唤醒线程返回null的msg, MessageQueue返回空msg即退出