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 ...
随机推荐
- 【USACO 3.1.1】最短网络
[描述] 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的场.当然,他需要你的帮助. 约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共 ...
- 【转载】Think as Customer 以客户为中心的测试理念
纵观各大公司的核心理念,往往都有一条类似“以客户为中心”的价值观.华为公司更是把“以客户为中心”放在其核心价值观的第一条,以显示它的重要性.从我 们入职培训开始,公司就反复强调并引导大家深入讨论,希望 ...
- jquery mobile listview列表属性(搜索自动填充检索效果)
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name ...
- jQuery中的阻止默认行为
在很多元素中都存在默认行为,例如表单中的submit按钮,a标签等等.如果想要消除其中的默认行为,就需要一个事件event的方法来消除他们的默认行为. 这个方法就是event.preventDefau ...
- JQuery相关的网络资源
jquery插件列表 国外网站:http://plugins.jquery.com/ 国内网站:http://www.oschina.net/project/tag/273/jquery
- 初涉JavaScript模式 (13) : 代码复用 【上】
引子 博客断了一段时间,不是不写,一是没时间,二是觉得自己沉淀不够,经过一段时间的学习和实战,今天来总结下一个老生常谈的东西: 代码复用. 为何复用 JS门槛低,故很多人以为写几个特效就会JS,其实真 ...
- [HttpClient]HttpClient简介
1. 前言 HTTP 协议可能是现在 Internet 上使用得最多.最重要的协议了,越来越多的 Java应用程序需要直接通过 HTTP 协议来访问网路资源.虽然在 JDK 的 java net包中已 ...
- MYSQL管理之主从同步管理 转载
MYSQL主从同步架构是目前使用最多的数据库架构之一,尤其是负载比较大的网站,因此对于主从同步的管理也就显得非常重要,新手往往在出现主从同步错误的时候不知道如何入手,这篇文章就是根据自己的经验来详细叙 ...
- thinkphp excel txt文件上传实现
<?php/************************************************************************************** *** ...
- SQL Server DAC 管理员专用连接
DAC 是Dedicated Administrator Connect 的缩写,是专用管理员连接通道,当SQL Server 因为资源不足而无法连接入系统的时候,管理员可通过该通道连接到数据,进行问 ...