试着从整体的角度上去简述Handler、Looper、MessageQueue
三者之间的关系,以及使用这三者构建的Android系统的异步消息通信机制。
三者之间的关系,一图胜千言。
一些术语:
- Message : 线程间通信的消息载体,存储于MessageQueue中。
- MessageQueue : 负责存储Message对象,每个线程只能关联一个MessageQueue。
- Looper :无限消息循环,不停的检索MessageQueue,每个线程只能关联一个Looper。
- Handler:负责消息的分发(将message添加到MessageQueue中)和处理。每个线程可以关联多个Handler。
概述
Android 应用初始化的时候,会创建一个主线,通常称为Main Thread,亦或是UI线程。在UI线程的初始化过程中,会创建一个Looper, 同时将此Looper与UI线程绑定,该Looper负责管理应用程序对象包括Activity、以及Activity的window、BroadcastReciver等的通信,一个线程只会有一个Looper实例。
在Looper实例的创建过程中,又会创建一个MessageQueue对象。MessageQueue 负责存储Message,但是Message的添加不是直接通过MessageQueue,而是通过与Looper对象的相关联的Handler。
MessageQueue是消息存储的场所,
Looper无线循环的检索MessageQueue中是否有需要处理的消息,检索到有message时,执行message的target(即Handler)的dispatchMessage方法。
Handler对象在创建时,默认会关联到创建它的当前线程以及当前线程的MessageQueue。默认的线程是不具有Looper以及MessageQueue对象的。使用Handler对象可以将Message和runnable投递到与当前线程相关联的MessageQueue中,同时,可以在message出栈的时候对其进行处理。
Handler的两个主要作用
a. 安排在将来的某个时间点执行message或者runnable。
b. 跨线程通信,可以通过其实现子线程和UI线程之间的通信。
在子线程更新UI的几种方式
- a. 使用Handler的send or post 系列的方法。
- b. 在Activity 中使用runUiOnThread(runnable)方法
- c. 使用View.post(runnable)方法
一些值得注意的地方
- a. 如果想要在自己创建的Thread中使用Looper,可以使用系统提供的HandlerThread类。
- b. 慎用Handler,Handler过长的生命周期会一直持有Activity,造成内存泄露。