Looper、Message、MessageQueue、Handler归纳总结
程序员文章站
2022-07-14 17:04:42
...
Message Queue 消息队列
MessageQueue是一个消息队列,用来存放通过Handler发布的消息。消息队列通常附属于某一个创建它的线程,可以通过Looper.myQueue()得到
当前线程的消息队列。如果没有消息队列对象则会抛出空指针异常
。Android在 第一次启动程序时会默认会为UI thread创建一个关联的消息队列,用来管理程序的一些上层组件,activities,broadcast receivers 等等。你可以在自己的子线程中创建Handler与UI thread通讯。也就是说我们程序一启动我们的UI线程也就是主线程就会有一个消息队列 ,而如果我们自己另外开启的一个子线程就不会有MessageQueue(消息队列)对象。
Message Queue按照先进先出执行。 每个message queue都会有一个对应的Handler。Handler会向message queue通过两种方法发送消息:sendMessage或post。这两种消息都会插在message queue队尾并按先进先出执行。但通过这两种方法发送的消息执行的方式略有不同:通过sendMessage发送的是一个message对象,会被Handler的handleMessage()函数处理;而通过post方法发送的是一个runnable对象,则会自己执行。
Handler
通过Handler你可以发布或者处理一个消息或者是一个Runnable的
实例。每个Handler都 会与唯一的一个线程以及该线程的消息队列关联。当你创建一个新的Handler时候,默认情况下,它将关联到创建它的这个线程和该线程的消息队列。也就是说,如果你通过Handler发 布消息的话,消息将只会发送到与它关联的这个消息队列,当然也只能处理该消息队列中的消息。这里大家就得理解一下了 也就是说我们 一个Handler对应一个线程以及附属于该线程的消息队列。
Looper Looper是每条线程里的Message Queue的管家。
Looper扮演着一个Handler和 消息队列之间通讯桥梁的角色。程序组件首先通过Handler把
消息传递给Looper,Looper把消息放入队列。Looper也把消息队列里的消息广播给所有的Handler,Handler接受到消息后调用handleMessage进行处理。
Android没有Global的Message Queue,而Android会自动替主线程(UI线程)建立Message Queue,但在子线程里并没有建立Message Queue。所以调用Looper.getMainLooper()得到的主线程的Looper不为NULL,但调用Looper.myLooper()得到当前线程的Looper就有可能为NULL,它不会抛空指针异常。Looper类为一个线程开启一个消息循环,里面有一个消息队列,新线程是没有开启消息循环的,所以需要用到Looper的方法创建消息循环(主线程除外,主线程会自动为其创建Looper对象,开启消息循环),MessageQueue存放消息和事件。
对于子线程使用Looper,API Doc提供了正确的使用方法:
package com.test;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
class LooperThread extends Thread {
public Handler mHandler;
public void run() {
Looper.prepare(); //创建本线程的Looper并创建一个MessageQueue
mHandler = new Handler() {
public void handleMessage(Message msg) {
// process incoming messages here
}
};
Looper.loop(); //开始运行Looper,监听Message Queue
}
}
这个Message机制的大概流程:1. 在Looper.loop()方法运行开始后,循环地按照接收顺序取出Message Queue里面的非NULL的Message。
2. 一开始Message Queue里面的Message都是NULL的。当Handler.sendMessage(Message)到Message Queue,该函数里面设置了那个Message对象的target属性是当前的Handler对象。随后Looper取出了那个Message,则调用该Message的target指向的Hander的dispatchMessage函数对Message进行处理。
在dispatchMessage方法里,如何处理Message则由用户指定,三个判断,优先级从高到低:
1) Message里面的Callback,一个实现了Runnable接口的对象,其中run函数做处理工作;
2) Handler里面的mCallback指向的一个实现了Callback接口的对象,由其handleMessage进行处理;
3) 处理消息Handler对象对应的类继承并实现了其中handleMessage函数,通过这个实现的handleMessage函数处理消息。
由此可见,我们实现的handleMessage方法是优先级最低的。
3. Handler处理完该Message (update UI) 后,Looper则设置该Message为NULL,以便回收!
通过分析Activity源码,我们知道每个Activity都有一个Looper,所以主线程在接收Message是不需要调用Looper.prepare()和Looper.loop(),但是非主线程是不带Looper的,当非主线程要接收来自主线程的消息是就需要调用Looper.prepare()和Looper.loop()。
demo1:Looper、Handler应用---实现主线程向子线程发送消息
Looper原型:
Looper.prepare()
Looper.loop
Looper.quit
代码:package com.test.looper;
import android.app.Activity;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
public class MainActivity extends Activity {
private LooperThread looperThread;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
looperThread = new LooperThread();
looperThread.start();
looperThread.getHandler().sendEmptyMessage(1);
}
class LooperThread extends Thread {
private Handler mHandler;
private final Object mSync = new Object();
public void run() {
Looper.prepare();
synchronized (mSync) {
mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
Log.d("CYQ", "--->" + msg);
}
};
mSync.notifyAll();
}
Looper.loop();
}
public Handler getHandler() {
synchronized (mSync) {
if (mHandler == null) {
try {
mSync.wait();
} catch (InterruptedException e) {
}
}
return mHandler;
}
}
public void exit() {
getHandler().post(new Runnable(){
public void run() {
Looper.myLooper().quit();
}});
}
}
}
注意一下几点:
1、new Handler()必须在子线程的run方法中,否则不是子线程的Handler
2、在getHandler方法中,加入同步防止线程start了,但是并没有run结束,若此时直接返回mHandler会是一个null,源码中有更稳定的实现。
参考:
4、http://byandby.iteye.com/blog/825071(基础概念)***
推荐阅读
-
AsyncTask陷阱之:Handler,Looper与MessageQueue的详解
-
Handler,Looper,MessageQueue流程梳理
-
Android异步2:深入详解 Handler+Looper+MessageQueue
-
Android Handler 机制 - Looper,Message,MessageQueue
-
handler,message,looper,messagequeue
-
Handler,Looper,Thread,Message,MessageQueue
-
Handler、Looper、Message、MessageQueue
-
Looper,MessageQueue,Message,Handler
-
异步消息处理(Message, Handler, MessageQueue, Looper)
-
Android消息通信机制Handler详解,Handler,Looper,MessageQueue,源码解析,讲解这几个类怎么配合工作的