(原)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的用法,请参见我的博客 ...
随机推荐
- bzoj4237: 稻草人 cdq分治 单调栈
目录 题目链接 题解 代码 题目链接 bzoj4237: 稻草人 题解 暴力统计是n^2的 考虑统计一段区间对另一端的贡献 对于y值cdq分治,降调一维 对于当前两个分治区间统计上面那部分对下面那部分 ...
- 洛谷.1110.[ZJOI2007]报表统计(Multiset)
题目链接 主要思路 /* 其实只需要multiset即可 对于询问1,删除.插入差值,输出最小元素 对于询问2,插入后用前驱后继更新 1.注意哨兵元素 2.注意multiset中删除时是删除某元素的一 ...
- pthread_once详解和使用
转自:pthread_once()函数详解 .pthread_once()使用 在多线程环境中,有些事仅需要执行一次.通常当初始化应用程序时,可以比较容易地将其放在main函数中.但当你写一个库时,就 ...
- react-native组件封装与传值
转载链接:http://www.ncloud.hk/%E6%8A%80%E6%9C%AF%E5%88%86%E4%BA%AB/react-native-component-packaging-and- ...
- spring cloud: 使用consul来替换eureka
eureka官方已经正式宣布:自2.0起不再维护该项目,并在github 项目wiki上放出了一段吓唬人的话: 大意就是:从2.x起,官方不会继续开发了,如果需要使用2.x,风险自负.但其实我觉得问题 ...
- .NET:Threading and Exceptions
Do handle exceptions in threads. Unhandled exceptions in threads, even background threads, generally ...
- CentOS 的 /etc/profile 和 ~/.bash_profile 及 .zshrc
交互式登陆shell 对于交互式的登陆shell而言,CentOS规定了startup文件的加载顺序如下: 登陆过程: 1. 读取并执行/etc/profile文件: 2. 读取并执行~/.bash_ ...
- Knockout.Js官网学习(checked 绑定)
前言 checked绑定是关联到checkable的form表单控件到view model上 - 例如checkbox(<input type='checkbox'>)或者radio bu ...
- Linux 保护文件 不给修改
chatter +i file 文件不能删除,不能更改,不能移动 chatter -i file 恢复 lsattr file 查看 ----i--------e-- file 修改会提示: f ...
- 最小生成树 Prim Kruskal
layout: post title: 最小生成树 Prim Kruskal date: 2017-04-29 tag: 数据结构和算法 --- 目录 TOC {:toc} 最小生成树Minimum ...