Android消息机制-Handler原理(三)
程序员文章站
2022-03-08 11:57:35
...
一 .Handler的执行过程
1.定义Handler对象,重写handleMessage方法
2.handler 对象调用sendMessage 发送message,sendMessage 最终调用 sendMessageAtTime
3.sendMessageAtTime方法又调用了 enqueueMessage 使message 加入到 消息队列 MessageQueue,并且执行了msg.target = this 把handler对象赋值给message对象的target属性
4.线程中的Looper执行loop()方法,不断从消息队列当中读取消息。
5.loop()取到消息后,执行 msg.target.dispatchMessage(msg) ,也就是执行Handler对象当中的dispatchMessage方法
6.最终dispatchMessage 方法,可以执行第一步handler对象重写的handleMessage继而完成了整个消息传递
补充 7.如果,第二步中Handler 使用post方法发送一个runable对象而非send方法,runable传递给了message的callback,最终在dispatchMessage 中,判断callback!=null从而执行了runable对象
二 .相关类
A.Handler:作用是发送消息,执行消息
Handler的相关方法已经介绍过了,这里 ,最终发送消息都指向了sendMessageAtTime(除了sendMessageAtFrontOfQueue)
//sendMessageAtTime源码
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis);
}
最终执行消息都指向了dispatchMessage
B. Message:消息,target属性携带handler对象,callback属性可携带Runable对象
C.MessageQueue:消息队列,一个线程只有一个消息队列
类似现实中买票,每个人都是一个messge,如果不排队窗口售票员处理不过来,票也容易卖重复了。排成一队,一个一个处理。
sendMessageAtTime中调用了MessageQueue 的 enqueueMessage 方法使消息加入消息队列。
Looper调用MessageQueue的next方法从消息队列中取消息。
D.Looper:循环从MessageQueue里面取消息,并dispatch调度消息。每个线程一个Looper实例
1. Looper才是使消息队列循环起来的类,在UI主线程中,Actitivy创建的时候,已经执行了Looper.loop() 。在Activity源码中定义了变量ActivityThread 类型的变量 mMainThread,他就代表了主线程。ActivityThread 中定义了Looper,并最终执行了Looper.loop()。所以在主线程中,可以直接发送消息,并且取消息。
2.但是在Thread中,并没有定义和调用Looper.loop(),这样你发消息取不出来,执行不了,所以,在子线程要想执行Handler 这一套机制,必须在Thread里调用Looper.loop()是消息循环起来
Handler机制的作用什么,是让线程A发消息,告诉B线程执行消息。
这里既可以子线程发送消息,让主线程执行消息; 又可以主线程发消息让子线程执行消息。
Handler 发消息的线程和消息执行的线程是两个概念。这里,子线程里给主线程send消息,会使消息在主线程执行。 主线程给子线程send消息,会使消息在子线程执行。
进一步,主线程在创建的时候,就已经执行了Looper.loop() 监听消息队列。 所以子线程发消息给主线程,可以随时就执行了
但是,主线程发消息给子线程,子线程默认又没有监听消息队列,发了消息没人收。所以才需要先执行 Looper.prepare() 使线程绑定Looper对象,然后执行Looper.loop() 使消息队列动起来,循环监听消息队列。
实际上,主线程发消息让子线程执行消息是不常见的,主要是为了解释清楚 Looper.prepare() 是和线程绑定,Looper.loop()
可以使线程循环监听消息队列。Looper才不管你是不是主线程,它只是让绑定它的线程具有循环监听消息队列的功能
上一篇: java字符串编码类型获取
下一篇: Java学习【Day 4】
推荐阅读
-
Android插件化原理解析--插件化加载机制
-
Android 图片的三级缓存机制实例分析
-
Android6.0权限机制(三):6.0以前国产手机权限处理
-
深入理解 Handler 消息机制
-
Android Handler机制初步分析
-
.net平台借助第三方推送服务在推送Android消息(极光推送)
-
Android面试:Android-Window机制原理之Token验证(为什么Application的Context不能show dialog)
-
从Handler.postDelayed来看看Android怎么实现处理延时消息
-
Android消息处理机制Looper和Handler详解
-
Android消息机制解析