Android Handler 异步消息处理机制
前言
在Android 多线程场景中,存在主线程和子线程之分,主线程是应用程序首次启动时自动开启的,子线程由人为创建和开启。主线程不允许执行耗时任务,子线程不允许更新UI控件(多个线程并发操作UI控件存在线程不安全),所以当某些耗时任务执行后需要更新UI控件时,通常由子线程去执行耗时任务,然后再根据任务执行结果由主线程(又称UI线程)更新响应的UI控件。这其中,子线程与主线程之间通常使用Handler异步消息处理机制完成通信。
Handler机制基本原理
Handler异步消息处理机制主要有4部分组成:Message,MessageQueue,Handler,Looper
- Message:存储线程需要传递的信息的对象。Message可以携带少量信息,用于不同线程之间的数据交换。
- MessageQueue:消息队列,先进先出,存储所有需要处理的消息。每个线程有一个MessageQueue。
- Handler:消息处理者,有两个功能:(1)通过Handler.sendMessage()方法将消息发送到MessageQueue中存储;(2)通过Handler.handleMessage对接收到的消息进行处理。
- Looper:MessageQueue管理者。每个线程只有一个Looper对象,通过死循环方式不断将MessageQueue中的消息取出,发送给对应的Handler处理。
UI控件更新中异步消息处理机制的整个流程如下图所示:首先主线程中创建Handler对象,并重写handleMessage()方法实现对不同消息的处理。然后子线程在需要更新UI时,调用并重写主线程创建的Handler对象的sendMessage()方法发送更新UI的消息。Handler将这些消息存放到MessageQueue中,Looper一直尝试从MessageQueue中取出消息,并回调dispatchMessage()方法发送给对应Handler的handleMessage()处理消息。
注意:在多线程通信中,一个线程只能有一个MessageQueue,对应一个Looper来管理,但一个线程可以创建多个Handler。当有多个Handler时,他们待处理的消息都会存放到这同一个MessageQueue中,Looper取出消息后,通过Message中的某些标识(Message.target)找到对应的Handler,然后将消息传给该Handler。上面的UI更新过程中,MessageQueue、Looper和Handler属于主线程,子线程只是调用主线程中的Handler对象方法。
使用方法示例
1 | public class MainActivity extends AppCompatActivity implements View.OnClickListener{ |
参考文章
- Android异步通信:图文详解Handler工作原理
- Android中的Thread, Looper和Handler机制(附带HandlerThread与AsyncTask)
- 一个线程可以有几个Looper?几个Handler?从Looper.prepare()来看看关于Looper的一些问题
- Android第一行代码(第2版)-第10章第2节Android多线程编程