Android消息机制

Handler + MessageQueue + Looper

enter image description here

跨线程通信:

最常见的例子: 网络请求更新UI

写一手Handler

问题1:为什么规定子线程修改UI ?

  • ANR
  • UI线程不安全

1. Handler

  1. 发送Message
    boolean sendMessageDelayed(Message msg, long delayMillis)

  2. 排队(根据时间)
    boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis)

  3. Message对象池

2. MessageQueue

单链表实现

  1. 链表插入操作
    boolean enqueueMessage(Message msg, long when)

  2. 下一条消息,没有就 阻塞
    系统消息 插队
    Message next()

3. Looper

  1. 确保当前线程有且仅有一个Looper
    void prepare()

  2. 开启循环
  • 读取MessageQueue的下一条Message
  • Message分发给相应的target
  • 回收Message
    void loop()

4. ThreadLocal

  • JMM ( Java Memory Model )

  • 线程私有数据存储类:set() , get()方法
    通过它可以在指定的线程中存储数据,数据存储后,只有在指定线程中可以获取到存储的数据,对于其他线程中则无法获取

  • 通过ThreadLocal获取Looper

架构图)

问题2:如何发现ANR ?

题外话:子线程更新UI

ViewRootImplcheckThread方法:


void checkThread() {
    if (mThread != Thread.currentThread()) {
        throw new CalledFromWrongThreadException(
                "Only the original thread that created a view hierarchy can touch its views.");
    }
}

适用DialogToast
别忘了Looper.quit();

部分参考网络