(原)Android在子线程用handler发送的消息,主线程是怎么loop到的?
另一方面,来看运行在main线程的handleMessage,调用它的地方是Handler的dispatchMessage,再往上推是Looper的loop方法调的handler的dispatchMessage,所以如果没猜错的话loop方法应该是main线程。
那问题来了,不是各个线程管理各自的MessageQueue吗?那运行在main线程的loop方法是怎么拿到我发到thread1的MessageQueue并处理它里边的Message的呢?
求大神解答,是我哪儿理解不对吗?
离苦得乐 众生皆苦首先,Handler,Looper,MessageQueue这三者如何关联的?这里拿最简单的new 一个无参Handler为例。在创建无参的Handler时会对其中变量MessageQueue赋值,这个值就是Looper对象的MessageQueue,那么这个Looper对象又是在那创建的呢?如果是在app进程中的话,在启动该app时会调用ActivityThread,main方法进入主线程,在main函数中会有初始化Looper,并调用looper.loop()轮询MessageQueue中的Message,这个Message是handler在调用sendMessage或者post时会将Message enqueue到MessageQueue中,这样Looper 就会loop 到Handler发送到MessageQueue中的Message,loop时就会dispatchMessage了,再然后就是Hanlder处理message了,在调用sendMessage时,handler必须要重写handleMessage方法。这样就完成了发送消息和处理消息。在app的进程中,thread1还是发送消息到主线程中的MessageQueue,这个MessageQueue在首次启动app时就在创建Looper时已经创建好了。那么如果不是在app进程怎么办呢?假如是在ActivityManagerService中使用Handler的话呢?ActivityManagerService可以理解为在system_server进程中的一个线程,在启动system_server时并没有像启动一个app进程那样系统已经创建好了Looper,那么我们如果要使用Handler机制,就必须要有Handler,Looper,MessageQueue,Message,一来我们可以自己手动调用Looper.prepare和Looper.loop,另外,系统也已经封装好了,就是HandlerThread。HandlerThread是一个Thread,在里面已经将Looper,MessageQueue准备好了,这时候创建Handler时,将HandlerThread的Looper传给Handler就行了,这样Handler,Looper,MessageQueue就都有了,就可以利用Handler机制进行线程间通信了。
西米 android framework/native, kernel. etc1.主线程是 有且仅有一个Looper对象, Looper对象里又有一个MessageQueue。
2. Looper 负责不停的loop,并调用Handler的handleMessage处理Message。
3. Handler 负责投递message, 以及提供处理消息的方法handleMessage。
4 任何非主线程, 想要给 主线程发message, 必须通过handler(该handler内部包含了主线程的Looper引用)
扩展下:
不只是涉及主线程, 任意 子线程之间要传递异步消息的话,也可以用handler, 该handler中引用的looper对象是属于那个线程的, 就会把消息投递给该线程, 并在该线程里执行 handleMessage方法。
请参考 Handler的几个构造方法。
杨强 android开发由于Handler是在主线程中new的,而Handler的构造函数中才给其成员变量mLooper赋的值:mLooper = Looper.myLooper();所以说在子线程中send的Message其实也是发到了main线程
例如mainHandler.sendEmptyMessage(0)这个函数,他入队消息的队列是mainHandler对应的MessageQueue中,跟调用发送消息的队列无关。
(原)Android在子线程用handler发送的消息,主线程是怎么loop到的?的更多相关文章
- 【Java面试题】30 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次,接着再回到主线程又循环100,如此循环50次,请写出程序。
题目如下: 子线程循环10次,接着主线程循环100,接着又回到子线程循环10次, 接着再回到主线程又循环100,如此循环50次 思路如下: 子线程语主线程为互斥,可用SYNCHRONIZED.很容易想 ...
- Java线程——线程习题(一)子线程执行10次后,主线程再运行5次,这样交替执行三遍
题目:子线程执行10次后,主线程再运行5次,这样交替执行三遍 代码如下: package com.itheima.gan; /** * 子线程执行10次后,主线程再运行5次,这样交替执行三遍 * @a ...
- C#子线程执行完后,调用主线程的方法
private delegate void CheckVersionNumber_CallBack(string str);//定义一个为委托 用于 检测版本 //检测版本private void m ...
- Android开发——子线程操作UI的几种方法
在Android项目中经常有碰到这样的问题,在子线程中完成耗时操作之后要更新UI,下面就自己经历的一些项目总结一下更新的方法: 在看方法之前需要了解一下Android中的消息机制. 转载请标明出处:h ...
- Android通过子线程更新UI的几种方式
一般情况下,UI的更新都少不了Handler,首先我们先了解一下Handler机制: Handler消息机制 定义 Message 线程间通信的数据单元,可通过message携带需要的数据创建对象:M ...
- Android开发 ---多线程操作:Handler对象,消息队列,异步任务下载
效果图: 1.activity_main.xml 描述:定义了六个按钮 <?xml version="1.0" encoding="utf-8"?> ...
- Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别?
一个帖子的整理: Handler一定要在主线程实例化吗?new Handler()和new Handler(Looper.getMainLooper())的区别如果你不带参数的实例化:Handler ...
- Android子线程创建Handler方法
如果我们想在子线程上创建Handler,通过直接new的出来是会报异常的比如: new Thread(new Runnable() { public void run() { Handler hand ...
- android基础---->子线程更新UI
和许多其他的GUI 库一样,Android 的UI 也是线程不安全的.也就是说,如果想要更新应用程序里的UI 元素,则必须在主线程中进行,否则就会出现异常.了解AsyncTask的用法,请参见我的博客 ...
随机推荐
- loj#6076「2017 山东一轮集训 Day6」三元组 莫比乌斯反演 + 三元环计数
题目大意: 给定\(a, b, c\),求\(\sum \limits_{i = 1}^a \sum \limits_{j = 1}^b \sum \limits_{k = 1}^c [(i, j) ...
- js中for in,of区别
let x; let a = ['a','b','c'] let b = {name:'LIUNAN',age:19} for(x of a){ document.write(x) } for(x i ...
- Codeforces Round #405 (rated, Div. 2, based on VK Cup 2017 Round 1) C. Bear and Different Names 贪心
C. Bear and Different Names 题目连接: http://codeforces.com/contest/791/problem/C Description In the arm ...
- linux <<eof
在平时的运维工作中,我们经常会碰到这样一个场景:执行脚本的时候,需要往一个文件里自动输入N行内容.如果是少数的几行内容,还可以用echo追加方式,但如果是很多行,那么单纯用echo追加的方式就显得愚蠢 ...
- protobuf 测试使用
1 介绍 Protocol buffers are a flexible, efficient, automated mechanism for serializing structure ...
- ${pageContext.request.contextPath}无法解析
摘要 突然出现无法解析${pageContext.request.contextPath}的问题,在点击<a href="${pageContext.request.contextPa ...
- dhtmlxtree 如何得到xml,json等文件中的自定义的属性值
先看代码: var TreeForJSON = new dhtmlXTreeObject('TreeForJSON', '100%', '100%', 0); TreeForJSON.setImage ...
- TCMalloc小记(转)
一. 原理 tcmalloc就是一个内存分配器,管理堆内存,主要影响malloc和free,用于降低频繁分配.释放内存造成的性能损耗,并且有效地控制内存碎片.glibc中的内存分配器是ptmalloc ...
- 快捷切换hosts的小工具:SwitchHosts!
Windows 绿色版本下载:http://oldj.github.io/SwitchHosts/. 日常开发工作中,我们可能经常需要切换各种 hosts 绑定,比如在本地开发时可能需要一个开发环境的 ...
- mysql 5.7中的threads
>desc threads; +---------------------+---------------------+------+-----+---------+-------+ | Fie ...