简介
Android线程为了随时接收消失处理,需要一套消息处理机制。应用程序通过消息驱动应用程序运行。
相关类 | 简介 |
---|---|
Thread | 消息队列需要在线程里面创建,并且在线程结束的问题循环接受消息 |
Looper | 消息泵,负责循环穿件消息队列,接受消息,分发消息 |
Handler | 负责发送消息和接受消息 |
MessageQueue | 消息队列,消息发送后会在消息队列里等待消息泵处理 |
Message | 具体的消息.被消息泵分发,被handler接受,被消息队列运输 |
Callback | Handler处理消息的一个接口 |
android消息机制主要流程
- App进程创建
- 初始化一个消息队列
- 主线程死循环读取消息队列
Android应用主线程通过创建消息队列,然后在无限循环中等待或获取消息队列传递的信息,然后处理。上面是主线程的消息机制流程,android允许子线程创建自己的消息循环.
相关类:MessageQueue,Looper,Handler
主线程的消息队列在系统创建应用程序的时候就进行了主线程的消息循环机制的配置。
frameworks/base/core/java/android/app/ActivityThread.java
public final class ActivityThread extends ClientTransactionHandler {
public static void main(String[] args) {
....
Looper.prepareMainLooper();
...
Looper.loop();
throw new RuntimeException("Main thread loop unexpectedly exited");
}
如果是子线程Looper.prepareMainLooper()换成Looper.prepare()
frameworks/base/core/java/android/os/Looper.java
public final class Looper {
public static void prepareMainLooper() {//1
prepare(false);
synchronized (Looper.class) {
if (sMainLooper != null) {
throw new IllegalStateException("The main Looper has already been prepared.");
}
sMainLooper = myLooper();
}
}
public static void prepare() {//2
prepare(true);
}
private static void prepare(boolean quitAllowed) {
if (sThreadLocal.get() != null) {
throw new RuntimeException("Only one Looper may be created per thread");
}
sThreadLocal.set(new Looper(quitAllowed));
}
private Looper(boolean quitAllowed) {//3
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
}
public void quit() {//4
mQueue.quit(false);
}
}
frameworks/base/core/java/android/os/MessageQueue.java
void quit(boolean safe) {
if (!mQuitAllowed) {
throw new IllegalStateException("Main thread not allowed to quit.");//5
}
......
}
上面的操作主要是配置初始化。主线程Looper.prepareMainLooper(),子线程Looper.prepare(),之所以主线程用了不同的方法,是因为主线程的消息机制不能停止,而子线程是用户自己创建的是可以停止.代码差异在于3处,当MessageQueue的参数是false时,当尝试结束Looper调用quit方法时,会报" throw new IllegalStateException(“Main thread not allowed to quit.”)",
有了消息队列,还有消息循环。通过循环获取消息池的信息,驱动程序。
当我们调用 Looper.loop();
/**
* Run the message queue in this thread. Be sure to call
* {@link #quit()} to end the loop.
*/
public static void loop() {
...
for (;;) {//1
Message msg = queue.next(); // might block //2
...
msg.target.dispatchMessage(msg);//3
...
}
}
1处是个无限循环,2处获取消息队列中的消息,然后分发给对应的handler