(原)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机制进行线程间通信了。

1.主线程是 有且仅有一个Looper对象, Looper对象里又有一个MessageQueue。
2. Looper 负责不停的loop,并调用Handler的handleMessage处理Message。
3. Handler 负责投递message, 以及提供处理消息的方法handleMessage。
4 任何非主线程, 想要给 主线程发message, 必须通过handler(该handler内部包含了主线程的Looper引用)
扩展下:
不只是涉及主线程, 任意 子线程之间要传递异步消息的话,也可以用handler, 该handler中引用的looper对象是属于那个线程的, 就会把消息投递给该线程, 并在该线程里执行 handleMessage方法。
请参考 Handler的几个构造方法。

由于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的用法,请参见我的博客 ...
随机推荐
- 2553 ACM N皇后 回溯递归
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2553 中文题目,题意很简单. 思路:听说这是学习递归的经典题目,就来试试,发现自己一点想法都没有,一遇到递 ...
- [HNOI2011]Problem B
Description: 给定\(a\),\(b\),\(c\),\(d\),\(k\) 求: \(\sum_{i=a}^{b} \sum_{j=c}^{d} gcd(i,j)==k\) \(T\)组 ...
- android View的点击无效的原因
点击事件不生效,原来是因为我在里面的 ImageView中添加了 android:clickable="true". 解决办法:删掉ImageView中的android:click ...
- unity 判断物体是否在视角内(巧妙!)
public var isRendering:boolean=false; private var lastTime:float=0; private var curtTime:float=0; fu ...
- Linux学习笔记15—RPM包的安装OR源码包的安装
RPM安装命令1. 安装一个rpm包rpm –ivh 包名“-i” : 安装的意思“-v” : 可视化“-h” : 显示安装进度另外在安装一个rpm包时常用的附带参数有:--force : 强制安装, ...
- 碰到在Windows中访问局域网文件夹, 提示无法访问时的解决办法
运行:gpedit.msc 找到下图的位置, 启用即可
- 什么是less?
什么是less? 简单的说,你可以在你的css文件中使用变量.函数等方式来编写你的css. less具有哪些功能? 混入(Mixins)——class中的class: 参数混入——可以传递参数的cla ...
- Linux--信号阻塞与屏蔽
1. sigprocmask函数提供屏蔽和解除屏蔽信号的功能. 从而实现关键代码的运行不被打断. 函数声明如下: int sigprocmask(int how, const sigset_t *se ...
- What is a UINavigationTransitionView
**AFAIK UINavigationTransitionView is a class used to animate UINavigationController child views aro ...
- Spring Boot中CrudRepository与JpaRepository Dao中JpaRepository和JpaSpecificationExecutor查询
原文地址 https://blog.csdn.net/xuemengrui12/article/details/80525227?utm_source=blogxgwz0 https://www.i ...