涉及到的知识点:
- Handler()
- Looper
- MessageQueue
- Message
- ThreadLocal:线程本地存储区(Thread Local Storage,简称为TLS),每个线程都有自己的私有的本地存储区域,不同线程之间彼此不能访问对方的TLS区域。
简单工作流程
class MainActivity : AppCompatActivity() {
companion object {
internal class MyHandler : Handler() {
override fun handleMessage(msg: Message) {
super.handleMessage(msg)
//处理消息
}}}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
MyHandler().sendMessage(null)
}
}
- Handler.sendMessage(msg)[msg.target = Handler]
- MessageQueue.enqueueMessage(msg, uptimeMillis)
- Looper.loop(){
msg = MessageQueue.next
msg.target.dispatchMessage(msg)//target = Handler} - Handler.dispatchMessage -> Handler.handleMessage()
Handler在子线程中创建失败
Looper
MessageQueue怎么存储消息
- 单链表存储,插入方便,不需要查找,直接拿链表头部处理
- 有序链表,按Message执行时间有序
怎么取MessageQueue中的消息并处理
- Looper.loop()方法在初始化Looper的时候调用,是一个死循环,内部不断从MessageQueue中取消息并处理(如果有消息)
public static void loop() {
final Looper me = myLooper();
final MessageQueue queue = me.mQueue;
// 一个死循环
for (;;) {
// 不断的从消息队列里面取消息
Message msg = queue.next(); // might block
if (msg == null) {
// No message indicates that the message queue is quitting.
return;
}
try {
// 通过 target 去 dispatchMessage 而 target 就是绑定的 Handler
msg.target.dispatchMessage(msg);
} finally {
// 消息回收循环利用
msg.recycleUnchecked();
}
}}
Looper.loop()怎么退出死循环
-
MessageQueue中的mQuitting = true的时候,MessageQueue.next()方法会返回一个null,在Looper.loo()中获取到msg为空的时候退出死循环。
-
Looper 中调用quit/quitSafely方法会调用MessageQueue的quit方法,此时会讲mQuitting置为true
Looper.class public void quit() {mQueue.quit(false);} public void quitSafely() {mQueue.quit(true);} MessageQueue.class void quit(boolean safe) { if (!mQuitAllowed) {throw new IllegalStateException("Main thread not allowed to quit.");} synchronized (this) { if (mQuitting) {return; } mQuitting = true; if (safe) {removeAllFutureMessagesLocked();} else { removeAllMessagesLocked(); } // We can assume mPtr != 0 because mQuitting was previously false. nativeWake(mPtr); }
网友评论