我们知道安卓中的UI线程不是线程安全的,我们不能在UI线程中进行耗时操作,通常我们的做法是开启一个子线程在子线程中处理耗时操作,但是安卓规定不允许在子线程中进行UI的更新操作,通常我们会通过Handler机制来完成该功能,即当子线程中耗时操作完成后,在子线程中通过Handler向主线程发送消息,在主线程中的Handler的handleMessage方法中处理接受到的消息。这就是安卓中的消息机制,安卓中的消息机制主要是指Handler的运行机制,但是Handler的运行需要底层的MessageQueue和Looper机制的支撑。
下面我们来详解讲解安卓中的消息循环机制,即Handler,MessageQueue,Looper机制。注意本博客属于安卓进阶内容,所以一些基础性的东西如果看官不懂情请自行百度解决。
首先我们来看一个标准的使用Handler机制的代码示范例子:
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare();
mHandler = new Handler() {
public void handleMessage(Message msg) {
// handle messages here
}
};
Looper.loop();
}
}
这段代码大家肯定都不陌生,因为这是安卓中使用Handler机制的一个最标准的代码示范,也许看官可能会说我在使用Handler的时候没使用Looper.prepare()与Looper.loop()
语句,那时因为我们使用Handler通常是在UI线程中,而UI线程已经默认为我们做好了这些准备工作,至于这个待会后面会讲到。之所以选择在一个子线程中创建Handler的例子来讲解,是因为这样能让我们更加清楚的明白安卓消息循环中Handler,MessageQueue,Looper这三者之间的关系,因为在主线程中很多细节都被掩藏起来了。
首先从这段代码可以看到这里涉及两个概念(事实上安卓中的消息循环机制涉及三个重要概念),这里先简单介绍下
Looper:消息循环,用于从MessageQueue消息队列中取出消息进行处理。
Handler:消息发送与处理,Handler通过sendMessage向消息队列MessageQueue中发送一条消息,通过handlerMessage来处理消息
MessageQueue:消息队列,用来存放Handler发送的消息,它仅仅用来存放消息
首先讲解一下安卓中的消息循环的整体过程,然后从上述的示范代码上进行详细的讲解。
安卓中的消息循环是使用Looper这个类来实现的,而Looper是基于线程的,即一个Looper对象与创建它的线程相关联,当使用 Looper.prepare()语句时它会创建一个Looper对象和一个MessageQueue对象,然后在创建Handler时会先获取到Handler所在的线程的Looper对象(如果调用的是无参构造函数时),通过这个Looper对象同时可以获得其MessageQueue对象,正因为如此相当于Handler与Looper相关联。这样通过Handler发送的消息才知道应该通过哪个Looper去进行处理。这是理解安卓整个消息循环机制核心,即MeaageQueue与Looper相关联,Handler与Looper相关联,从这里也可以看出Looper是安卓消息循环机制的核心。
下面以上述示范代码为例进行详细讲解。
首先我们来看一下 Looper.prepare()语句,即看一下p