理解Message, MessageQueue, Handler
一没此看时候就理解, 后面问到有忘记了, 这里这个笔记.
"Looper不断获取MessageQueue中的一个Message, 然后交给Hander处理."
一 Message---信使
先看图
作为一个信使当然是用来携带信息了 arg1, arg携带基本数据, obj携带实体, what---哪个消息
一般通过如下方式, 先从消息池中获取, 没有就创建
二. MessageQueue消息队列---水管
内部相当一个队列仓库, 实现了enqueueMessage(), next()一些存取消息算法
三. Handler消息处理者--干活出力的
负责创建消息并往MessageQueue存消息和处理消息
1. 存消息---post(...), postAtTime(...) 最终都是调用 enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) 。 我们看msg.target =this; 把Handler绑定给消息, 这样当取出消息时就能交给相应的Handler来处理。 queue.enqueueMessage(msg, uptimeMillis);就是往队列中存消息了
2. 处理消息----当Looper从MessageQueue取出一个消息, msg.target.dispatchMessage(msg);让消息target处理消息, 而这个target就是上面创建消息传入Handler, 最终就有Handler处理消息
四. Looper---轮询器
轮询取出当前线程的MessageQueue中的消息并最终由Message分发消息。看下它的成员
创建Looper
线程中调prepare创建一个Looper, 会同时创建了一个消息队列,所以Looper中有且只有一个MessageQueue。 下一步sThreadLocal.set(new Looper(quitAllowed));把Looper存入sThreadLocal中。
看下ThreadLocal, 字面上意思,就是线程的变量。 当我们调用其中的set(),方法, 就存一个变量到当前线程中, 调用get(), 也是从当前线程中获取这个变量。 其他线程获取不到另一个线程的变量。所以Looper中的 static final ThreadLocalsThreadLocal =new ThreadLocal(); 表示存储了当前线程的Looper。
再看下图, sThreadLocal.get()不为空, 调prepare()会报错, 这就限定了当前线程只能调一次prepare(), 创建一个Looper。 也就是一个线程中最多只有一个Looper, 一个Looper中有一个MessageQueue。 一个MessageQueue中可以有很多Message, 而每个Message绑定不同的Handler。
最后看下四者的关系图