### **概述**
Android应用程序与传统的PC应用程序一样,都是消息驱动的。也就是说,在Android应用程序主线程中,所有函数都是在一个消息循环中执行的。Android应用程序其它线程,也可以像主线程一样,拥有消息循环。Android应用程序主线程是一个特殊的线程,因为它同时也是UI线程以及触摸屏、键盘等输入事件处理线程。主线程对消息循环很敏感,一旦发生阻塞,就会影响UI的流畅度,甚至发生ANR问题。
主要讲Android应用程序线程消息循环原理,主要涉及到Handler和Looper两个类,以及根据消息循环的不同使用场景,总结出三种线程使用模型。掌握Android应用程序消息处理机制,有助于我们熟练地使用同步和异步编程,提高程序的运行性能。
* 线程与消息的关系
* 线程的消息队列创建
* 线程的消息循环
* 线程的消息发送
* 线程的消息处理
* 消息在异步任务的应用
#### **线程与消息的关系**
**Android应用程序有两种类型的线程**
* 带有消息队列,用来执行循环性任务
* 有消息时就处理
* 没有消息时就睡眠
* 例子:主线程、android.os.HandlerThread
* 没有消息队列,用来执行一次性任务
* 任务一旦执行完成便退出
* 例子:java.lang.Thread
**带有消息队列的线程四要素**
* Message(消息)
* MessageQueue(消息队列)
* Looper(消息循环)
* Handler(消息发送和处理)
**Message、 MessageQueue、 Looper和Handler的交互过程**

#### **线程的消息队列创建**
**MessageQueue与Looper的关系**

**例1:ServerThread**

**例2:ActivityThread**

**Looper.prepare/prepareMainLooper**

**new Looper – 创建Java层的Looper**

**new MessageQueue**

**nativeInit**

**new NativeMessageQueue**

**new Looper – 创建C++层的Looper**

**pipe**
* 一种进程/线程间通信机制
* 包含一个写端文件描述符和一个读端文件描述符
* Looper通过读端文件描述符等待新消息的到来
* Handler通过写端文件描述符通知Looper新消息的到来

**epoll**
* 一种I/O多路复用技术,select/poll加强版
* epoll_create:创建一个epoll句柄
* epoll_ctl:设置要监控的文件描述符
* epoll_wait:等待监控的文件描述符发生IO事件
* Looper利用epoll来监控消息队列是否有新的消息,也就是监控消息管道的读端文件描述符
**为什么要用epoll**
Looper除了监控消息管道之外,还需要监控其它文件描述符,例如,用来接收键盘/触摸屏事件的文件描述符
#### **线程的消息循环**
**例1:ServerThread**

**例2:ActivityThread**

**Looper.loop – Java层的Looper**

**MessageQueue.next**

**nativePollOnce**

**NativeMessageQueue.pollOnce**

**Looper.pollOnce – C++层的Looper**

**Looper.pollInner**

**Looper.awoken**

#### **线程的消息发送**
**常用的消息发送接口**
* Handler.sendMessage
带一个Message参数,用来描述消息的内容
* Handler.post
带一个Runnable参数,会被转换为一个Message参数
**Message**

**Handler.sendMessage/post**

**Handler.sendMessageDelayed**

**Handler.sendMessageAtTime**

**Handler.enqueueMessage**

**MessageQueue.enqueueMessage**

**备注**:
mBlocked:Indicates whether next() is blocked waiting in pollOnce() with a non-zero timeout.
**nativeWake**

**NativeMessageQueue.wake**

**Looper.wake**

**回顾消息循环过程**

**Handler.dispatchMessage**

#### **消息在异步任务的应用**
**在主线程为什么要用异步任务?**
* 主线程任务繁重
* 执行组件生命周期函数
* 执行业务逻辑
* 执行用户交互
* 执行UI渲染
* 主线程处理某一个消息时间过长时会产生ANR
* Service生命周期函数 – 20s
* Broadcast Receiver接收前台优先级广播函数 –10s
* Broadcast Receiver接收后台优先级广播函数 – 60s
* 影响输入事件处理的函数 – 5s
* 影响进程启动的函数 – 10s
* 影响Activity切换的函数– 2s
**备注**:
一个进程如果正在接收一个前台优先级广播,那么它所在的进程调度组就为Process.THREAD_GROUP_DEFAULT ,如果是正在接收后台优先级广播,那么它所在的进程调度组就为Process.THREAD_GROUP_BG_NONINTERACTIVE。发送广播时,通过Intent.FLAG_RECEIVER_FOREGROUND标志来指定是前台优先级还是后台优先级
**基于消息的异步任务接口**
* android.os.HandlerThread
适合用来处于不需要更新UI的后台任务
* android.os.AyncTask
适合用来处于需要更新UI的后台任务
**android.os.HandlerThread**

**启动HandlerThread**
~~~
HandlerThread handlerThread = new HandlerThread("Handler Thread");
handlerThread.start();
~~~
**向HandlerThread分配任务**

~~~
ThreadTask threadTask = new ThreadTask();
Handler handler = new Handler(handlerThread.getLooper());
handler.post(threadTask);
~~~
**退出HandlerThread**
~~~
handlerThread.quit();
~~~

**android.os.AyncTask**
* 在进程内维护一个线程池来执行任务
* 任务在开始执行、执行过程以及结束执行时均可以与主线程进行交互
* 任务是通过一个Handler向主线程发送消息以达到交互的目的
**例子**

**AysnTask的相关成员变量定义**

**用来向主线程发送消息的InternalHandler**

**任务执行过程或者结果数据--AsyncTaskResult**

**创建任务**

**执行任务**


**触发AsyncTask.doInBackground在工作线程中被调用**
**更新任务进度**


**MESSAGE_POST_PROGRESS通过sHandler发送到主线程的消息队列**
**触发AsyncTask.onProgressUpdate在主线程中被**
**任务结束时,MESSAGE_POST_RESULT通过sHandler发送到主线程的消息队列,触发AsyncTask.finish在主线程中被调用**



**进一步触发AsyncTask.onPostExecute在主线程中被调用**
**任务中途取消时,MESSAGE_POST_CANCEL通过sHandler发送到主线程的消息队列,触发AsyncTask.onCancel在主线程中被调用**



- 前言
- Android组件设计思想
- Android源代码开发和调试环境搭建
- Android源代码下载和编译
- Android源代码情景分析法
- Android源代码调试分析法
- 手把手教你为手机编译ROM
- 在Ubuntu上下载、编译和安装Android最新源代码
- 在Ubuntu上下载、编译和安装Android最新内核源代码(Linux Kernel)
- 如何单独编译Android源代码中的模块
- 在Ubuntu上为Android系统编写Linux内核驱动程序
- 在Ubuntu上为Android系统内置C可执行程序测试Linux内核驱动程序
- 在Ubuntu上为Android增加硬件抽象层(HAL)模块访问Linux内核驱动程序
- 在Ubuntu为Android硬件抽象层(HAL)模块编写JNI方法提供Java访问硬件服务接口
- 在Ubuntu上为Android系统的Application Frameworks层增加硬件访问服务
- 在Ubuntu上为Android系统内置Java应用程序测试Application Frameworks层的硬件服务
- Android源代码仓库及其管理工具Repo分析
- Android编译系统简要介绍和学习计划
- Android编译系统环境初始化过程分析
- Android源代码编译命令m/mm/mmm/make分析
- Android系统镜像文件的打包过程分析
- 从CM刷机过程和原理分析Android系统结构
- Android系统架构概述
- Android系统整体架构
- android专用驱动
- Android硬件抽象层HAL
- Android应用程序组件
- Android应用程序框架
- Android用户界面架构
- Android虚拟机之Dalvik虚拟机
- Android硬件抽象层
- Android硬件抽象层(HAL)概要介绍和学习计划
- Android专用驱动
- Android Logger驱动系统
- Android日志系统驱动程序Logger源代码分析
- Android应用程序框架层和系统运行库层日志系统源代码分析
- Android日志系统Logcat源代码简要分析
- Android Binder驱动系统
- Android进程间通信(IPC)机制Binder简要介绍和学习计划
- 浅谈Service Manager成为Android进程间通信(IPC)机制Binder守护进程之路
- 浅谈Android系统进程间通信(IPC)机制Binder中的Server和Client获得Service Manager接口之路
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信Binder机制在应用程序框架层的Java接口源代码分析
- Android Ashmem驱动系统
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)简要介绍和学习计划
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)驱动程序源代码分析
- Android系统匿名共享内存Ashmem(Anonymous Shared Memory)在进程间共享的原理分析
- Android系统匿名共享内存(Anonymous Shared Memory)C++调用接口分析
- Android应用程序进程管理
- Android应用程序进程启动过程的源代码分析
- Android系统进程Zygote启动过程的源代码分析
- Android系统默认Home应用程序(Launcher)的启动过程源代码分析
- Android应用程序消息机制
- Android应用程序消息处理机制(Looper、Handler)分析
- Android应用程序线程消息循环模型分析
- Android应用程序输入事件分发和处理机制
- Android应用程序键盘(Keyboard)消息处理机制分析
- Android应用程序UI架构
- Android系统的开机画面显示过程分析
- Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析
- SurfaceFlinger
- Android系统Surface机制的SurfaceFlinger服务
- SurfaceFlinger服务简要介绍和学习计划
- 启动过程分析
- 对帧缓冲区(Frame Buffer)的管理分析
- 线程模型分析
- 渲染应用程序UI的过程分析
- Android应用程序与SurfaceFlinger服务的关系
- 概述和学习计划
- 连接过程分析
- 共享UI元数据(SharedClient)的创建过程分析
- 创建Surface的过程分析
- 渲染Surface的过程分析
- Android应用程序窗口(Activity)
- 实现框架简要介绍和学习计划
- 运行上下文环境(Context)的创建过程分析
- 窗口对象(Window)的创建过程分析
- 视图对象(View)的创建过程分析
- 与WindowManagerService服务的连接过程分析
- 绘图表面(Surface)的创建过程分析
- 测量(Measure)、布局(Layout)和绘制(Draw)过程分析
- WindowManagerService
- WindowManagerService的简要介绍和学习计划
- 计算Activity窗口大小的过程分析
- 对窗口的组织方式分析
- 对输入法窗口(Input Method Window)的管理分析
- 对壁纸窗口(Wallpaper Window)的管理分析
- 计算窗口Z轴位置的过程分析
- 显示Activity组件的启动窗口(Starting Window)的过程分析
- 切换Activity窗口(App Transition)的过程分析
- 显示窗口动画的原理分析
- Android控件TextView的实现原理分析
- Android视图SurfaceView的实现原理分析
- Android应用程序UI硬件加速渲染
- 简要介绍和学习计划
- 环境初始化过程分析
- 预加载资源地图集服务(Asset Atlas Service)分析
- Display List构建过程分析
- Display List渲染过程分析
- 动画执行过程分析
- Android应用程序资源管理框架
- Android资源管理框架(Asset Manager)
- Asset Manager 简要介绍和学习计划
- 编译和打包过程分析
- Asset Manager的创建过程分析
- 查找过程分析
- Dalvik虚拟机和ART虚拟机
- Dalvik虚拟机
- Dalvik虚拟机简要介绍和学习计划
- Dalvik虚拟机的启动过程分析
- Dalvik虚拟机的运行过程分析
- Dalvik虚拟机JNI方法的注册过程分析
- Dalvik虚拟机进程和线程的创建过程分析
- Dalvik虚拟机垃圾收集机制简要介绍和学习计划
- Dalvik虚拟机Java堆创建过程分析
- Dalvik虚拟机为新创建对象分配内存的过程分析
- Dalvik虚拟机垃圾收集(GC)过程分析
- ART虚拟机
- Android ART运行时无缝替换Dalvik虚拟机的过程分析
- Android运行时ART简要介绍和学习计划
- Android运行时ART加载OAT文件的过程分析
- Android运行时ART加载类和方法的过程分析
- Android运行时ART执行类方法的过程分析
- ART运行时垃圾收集机制简要介绍和学习计划
- ART运行时Java堆创建过程分析
- ART运行时为新创建对象分配内存的过程分析
- ART运行时垃圾收集(GC)过程分析
- ART运行时Compacting GC简要介绍和学习计划
- ART运行时Compacting GC堆创建过程分析
- ART运行时Compacting GC为新创建对象分配内存的过程分析
- ART运行时Semi-Space(SS)和Generational Semi-Space(GSS)GC执行过程分析
- ART运行时Mark-Compact( MC)GC执行过程分析
- ART运行时Foreground GC和Background GC切换过程分析
- Android安全机制
- SEAndroid安全机制简要介绍和学习计划
- SEAndroid安全机制框架分析
- SEAndroid安全机制中的文件安全上下文关联分析
- SEAndroid安全机制中的进程安全上下文关联分析
- SEAndroid安全机制对Android属性访问的保护分析
- SEAndroid安全机制对Binder IPC的保护分析
- 从NDK在非Root手机上的调试原理探讨Android的安全机制
- APK防反编译
- Android视频硬解稳定性问题探讨和处理
- Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析
- Android应用程序安装过程源代码分析
- Android应用程序启动过程源代码分析
- 四大组件源代码分析
- Activity
- Android应用程序的Activity启动过程简要介绍和学习计划
- Android应用程序内部启动Activity过程(startActivity)的源代码分析
- 解开Android应用程序组件Activity的"singleTask"之谜
- Android应用程序在新的进程中启动新的Activity的方法和过程分析
- Service
- Android应用程序绑定服务(bindService)的过程源代码分析
- ContentProvider
- Android应用程序组件Content Provider简要介绍和学习计划
- Android应用程序组件Content Provider应用实例
- Android应用程序组件Content Provider的启动过程源代码分析
- Android应用程序组件Content Provider在应用程序之间共享数据的原理分析
- Android应用程序组件Content Provider的共享数据更新通知机制分析
- BroadcastReceiver
- Android系统中的广播(Broadcast)机制简要介绍和学习计划
- Android应用程序注册广播接收器(registerReceiver)的过程分析
- Android应用程序发送广播(sendBroadcast)的过程分析