Android - 消息机制与线程通信
以下资料摘录整理自老罗的Android之旅博客,是对老罗的博客关于Android底层原理的一个抽象的知识概括总结(如有错误欢迎指出)(侵删):
http://blog.csdn.net/luoshengyang/article/details/8923485
http://blog.csdn.net/luoshengyang/article/details/12957169
整理by Doing
消息机制
- 带有消息队列,用来执行循环性任务:有消息时就处理;没有消息时就睡眠;(例子:主线程、android.os.HandlerThread)
- 没有消息队列,用来执行一次性任务:任务一旦执行完成便退出;(例子:java.lang.Thread)


消息循环
- 创建Java层的Looper: 在Java层,创建了一个Looper对象,这个Looper对象是用来进入消息循环的,它的内部有一个消息队列MessageQueue对象mQueue:

- Looper类的静态成员函数prepareMainLooper是专门应用程序的主线程调用的,应用程序的其它子线程都不应该调用这个函数来在本线程中创建消息循环对象,而应该调用prepare函数来在本线程中创建消息循环对象:其它地方能够方便地通过Looper类的getMainLooper函数来获得应用程序主线程中的消息循环对象,进而能够向应用程序主线程发送消息。

- 创建JNI层的Looper对象:在JNI层,创建了一个NativeMessageQueue对象,这个NativeMessageQueue对象保存在Java层的消息队列对象mQueue的成员变量mPtr中; 在C++层,创建了一个Looper对象,保存在JNI层的NativeMessageQueue对象的成员变量mLooper中,这个对象的作用是,当Java层的消息队列中没有消息时,就使Android应用程序主线程进入等待状态,而当Java层的消息队列中来了新的消息后,就唤醒Android应用程序的主线程来处理这个消息:
- 一种进程/线程间通信机制
- 包含一个写端文件描述符和一个读端文件描述符
- Looper通过读端文件描述符等待新消息的到来
- Handler通过写端文件描述符通知Looper新消息的到来

- 一种I/O多路复用技术,select/poll加强版
- epoll_create:创建一个epoll句柄
- epoll_ctl:设置要监控的文件描述符
- epoll_wait:等待监控的文件描述符发生IO事件
消息的发送
- 在ActivityThread.queueOrSendMessage函数中,把上面传进来的参数封装成一个Message对象msg,然后通过mH.sendMessage函数把这个消息对象msg加入到应用程序的消息队列中去。(mH为H类,继承于Handler类)
- 在Looper::wake()中,通过打开文件描述符mWakeWritePipeFd往管道的写入一个"W"字符串。其实,往管道写入什么内容并不重要,往管道写入内容的目的是为了唤醒应用程序的主线程。
- Handler.sendMessage:带一个Message参数,用来描述消息的内容
- Handler.post:带一个Runnable参数,会被转换为一个Message参数

消息的处理
总结
消息在异步任务的应用
- 执行组件生命周期函数
- 执行业务逻辑
- 执行用户交互
- 执行UI渲染
- Service生命周期函数 – 20s
- Broadcast Receiver接收前台优先级广播函数 –10s
- Broadcast Receiver接收后台优先级广播函数 – 60s
- 影响输入事件处理的函数 – 5s
- 影响进程启动的函数 – 10s
- 影响Activity切换的函数– 2s
- android.os.HandlerThread:适合用来处于不需要更新UI的后台任务
- android.os.AyncTask:适合用来处于需要更新UI的后台任务
HandlerThread
- HandlerThread类继承了Thread类,因此,通过它可以在应用程序中创建一个子线程;其次,在它的run函数中,首先是调用Looper类的静态成员函数prepare来准备一个消息循环对象,然后会进入一个消息循环中,因此,这个子线程可以常驻在应用程序中,直到它接收收到一个退出消息为止。
- Looper类的myLooper成员函数将这个子线程中的消息循环对象保存在HandlerThread类中的成员变量mLooper中, 这样,其它地方就可以方便地通过它的getLooper函数来获得这个消息循环对象了,有了这个消息循环对象后,就可以往这个子线程的消息队列中发送消息,通知这个子线程执行特定的任务了

AsyncTask类
- 内部实现ThreadPoolExecutor类线程池
- 获取创建AsyncTask对象的当前所在线程的Handler进行消息发送和处理
- 当第一次创建一个AsyncTask对象时,首先会创建一个线程池sExecutor(ThreadPoolExecutor类,是Java提供的多线程机制之一。)
- ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
- BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory)
- 创建好了线程池后,再创建一个消息处理器:
- 创建AsyncTask对象,即执行AsyncTask类的构造函数:
- public AsyncTask() {
- mWorker = new WorkerRunnable<Params, Result>() {
- public Result call() throws Exception {
- ......
- return doInBackground(mParams);
- }
- };
- mFuture = new FutureTask<Result>(mWorker) {
- @Override
- protected void done() {
- Message message;
- Result result = null;
- try {
- result = get();
- } catch (InterruptedException e) {
- android.util.Log.w(LOG_TAG, e);
- } catch (ExecutionException e) {
- throw new RuntimeException("An error occured while executing doInBackground()",
- e.getCause());
- } catch (CancellationException e) {
- message = sHandler.obtainMessage(MESSAGE_POST_CANCEL,
- new AsyncTaskResult<Result>(AsyncTask.this, (Result[]) null));
- message.sendToTarget();
- return;
- } catch (Throwable t) {
- throw new RuntimeException("An error occured while executing "
- + "doInBackground()", t);
- }
- message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
- new AsyncTaskResult<Result>(AsyncTask.this, result));
- message.sendToTarget();
- }
- };
- }
- private static abstract class WorkerRunnable<Params, Result> implements Callable<Result> {
- Params[] mParams;
- }
- public final AsyncTask<Params, Progress, Result> execute(Params... params) {
- ......
- mWorker.mParams = params;
- sExecutor.execute(mFuture);
- return this;
- }
- mWorker = new WorkerRunnable<Params, Result>() {
- public Result call() throws Exception {
- ......
- return doInBackground(mParams);
- }
- };
- private static class AsyncTaskResult<Data> {
- final AsyncTask mTask;
- final Data[] mData;
- AsyncTaskResult(AsyncTask task, Data... data) {
- mTask = task;
- mData = data;
- }
- }
- message = sHandler.obtainMessage(MESSAGE_POST_RESULT,
- new AsyncTaskResult<Result>(AsyncTask.this, result));
- message.sendToTarget();
- private static class InternalHandler extends Handler {
- @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"})
- @Override
- public void handleMessage(Message msg) {
- AsyncTaskResult result = (AsyncTaskResult) msg.obj;
- switch (msg.what) {
- case MESSAGE_POST_RESULT:
- // There is only one result
- result.mTask.finish(result.mData[0]);
- break;
- ......
- }
- }
- }
- private void finish(Result result) {
- ......
- onPostExecute(result);
- ......
- }
- 在任务执行的过程当中,即执行doInBackground函数时候,可能通过调用publishProgress函数来将中间结果封装成一个消息发送到应用程序主线程中的消息队列中去,这个消息最终也是由InternalHandler类的handleMessage函数来处理的(这个函数是在应用程序的主线程中执行的,因此,它和前面的onPostExecute函数一样,可以操作应用程序的界面):
- protected final void publishProgress(Progress... values) {
- sHandler.obtainMessage(MESSAGE_POST_PROGRESS,
- new AsyncTaskResult<Progress>(this, values)).sendToTarget();
- }
键盘(Keyboard)消息处理机制
InputManager的初始化工作
应用程序注册键盘消息接收通道的过程
InputManager分发键盘消息给应用程序的过程
应用程序注销键盘消息接收通道的过程
Android - 消息机制与线程通信的更多相关文章
- Android消息机制
每一个Android应用在启动的时候都会创建一个线程,这个线程被称为主线程或者UI线程,Android应用的所有操作默认都会运行在这个线程中. 但是当我们想要进行数据请求,图片下载,或者其他耗时操作时 ...
- Android消息机制:Looper,MessageQueue,Message与handler
Android消息机制好多人都讲过,但是自己去翻源码的时候才能明白. 今天试着讲一下,因为目标是讲清楚整体逻辑,所以不追究细节. Message是消息机制的核心,所以从Message讲起. 1.Mes ...
- Android开发之漫漫长途 ⅥI——Android消息机制(Looper Handler MessageQueue Message)
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...
- Android开发之漫漫长途 Ⅶ——Android消息机制(Looper Handler MessageQueue Message)
该文章是一个系列文章,是本人在Android开发的漫漫长途上的一点感想和记录,我会尽量按照先易后难的顺序进行编写该系列.该系列引用了<Android开发艺术探索>以及<深入理解And ...
- android 进程间通信 messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯? android 消息机制 进程间 android 进程间 可以用 handler么 messenger 与 handler 机制 messenger 机制 是不是 就是 handler 机制 或 , 是不是就是 消息机制 android messenge
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha messenger 是什么 binder 跟 aidl 区别 intent 进程间 通讯 ...
- Android 进阶14:源码解读 Android 消息机制( Message MessageQueue Handler Looper)
不要心急,一点一点的进步才是最靠谱的. 读完本文你将了解: 前言 Message 如何获取一个消息 Messageobtain 消息的回收利用 MessageQueue MessageQueue 的属 ...
- Android消息机制探索(Handler,Looper,Message,MessageQueue)
概览 Android消息机制是Android操作系统中比较重要的一块.具体使用方法在这里不再阐述,可以参考Android的官方开发文档. 消息机制的主要用途有两方面: 1.线程之间的通信.比如在子线程 ...
- Android进阶——Android消息机制之Looper、Handler、MessageQueen
Android消息机制可以说是我们Android工程师面试题中的必考题,弄懂它的原理是我们避不开的任务,所以长痛不如短痛,花点时间干掉他,废话不多说,开车啦 在安卓开发中,常常会遇到获取数据后更新UI ...
- Android消息机制不完全解析(上)
Handler和Message是Android开发者常用的两个API,我一直对于它的内部实现比较好奇,所以用空闲的时间,阅读了一下他们的源码. 相关的Java Class: androi ...
随机推荐
- Hibernate 性能优化之懒加载
针对数据库中的大数据,不希望特别早的加载到内存中,当用到它的时候才加载 懒加载分为:类的懒加载.集合的懒加载.单端关联的懒加载 类的懒加载 1.在默认情况下,类就是执行懒加载 2. ...
- Java笔试知识总结(第一回)
- BroadcastReceiver监听电量变化
用BroadcastReceiver监听电量的变化,可以实现BroadcastReceiver接收电量变化的广播,然后获取电量百分比信息. BatteryChangedReceiver.java pu ...
- 事件的委托处理(Event Delegation)
javascript的事件模型,采用”冒泡”模式,也就是说,子元素的事件会逐级向上”冒泡”,成为父元素的事件. 利用这一点,可以大大简化事件的绑定.比如,有一个表格(table元素),里面有100个格 ...
- Java中的继承与组合
本文主要说明Java中继承与组合的概念,以及它们之间的联系与区别.首先文章会给出一小段代码示例,用于展示到底什么是继承.然后演示如何通过“组合”来改进这种继承的设计机制.最后总结这两者的应用场景,即到 ...
- 7 Reverse Integer(数字反转Easy)
题目意思:int数字反转 考虑:越界问题 class Solution { public: int reverse(int x) { ; while(x){ ans=ans*+x%; x=x/; } ...
- Maven 安装记
java初学者 昨天通m2e插件把maven项目导入eclipse的时候各种bug,看了各家技术博客,决定安装maven好好了解下. 安装maven也是一波三折的,先是看各种安装指导,结果环境变量都没 ...
- php回调函数callback函数实例
<?php // 将文本中的年份增加一年. $text = "April fools day is 04/01/2002\n"; $text.= "Last chr ...
- 防止SQL注入攻击,数据库操作类
如果不规避,在黑窗口里面输入内容时利用拼接语句可以对数据进行攻击 如:输入Code值 p001' union select * from Info where '1'='1 //这样可以查询到所有数据 ...
- C++11原子操作性能测试
测试结论是发现C++11原子操作在性能上,比以往用到的InterlockedIncrement或__sync_add_and_fetch性能上慢了1倍左右. 另外补充一点,在对原子变量进行比较的时候, ...