Message Looper Handler MessageQueue
程序员文章站
2022-07-14 17:07:42
...
大概过程:
1.新建线程调用Looper.prepare,初始化和Looper 和 MessageQueue
2.Looper.loop() 循环queue.next() 并 分发消息dispatchMessage
3.Handler.sendMessage -- enqueueMessage把消息连到Message.next上,如链表结构,就放到了消息队列(MessageQueue)
4.dispatchMessage -- handleMessage Looper分发消息之后,handler来处理消息
-----------------1./frameworks/base/core/java/android/os/Looper.java--------------
27/**
28 * Class used to run a message loop for a thread. Threads by default do
29 * not have a message loop associated with them; to create one, call
30 * {@link #prepare} in the thread that is to run the loop, and then
31 * {@link #loop} to have it process messages until the loop is stopped.
32 *
33 * <p>Most interaction with a message loop is through the
34 * {@link Handler} class.
35 *
36 * <p>This is a typical example of the implementation of a Looper thread,
37 * using the separation of {@link #prepare} and {@link #loop} to create an
38 * initial Handler to communicate with the Looper.
39 *
40 * <pre>
41 * class LooperThread extends Thread {
42 * public Handler mHandler;
43 *
44 * public void run() {
45 * Looper.prepare();
46 *
47 * mHandler = new Handler() {
48 * public void handleMessage(Message msg) {
49 * // process incoming messages here
50 * }
51 * };
52 *
53 * Looper.loop();
54 * }
55 * }</pre>
56 */
-----------------------2.Looper.prepare() 线程使用就是new Looper ,然后在创建MessageQueue------------
89 public static void prepare() {
90 prepare(true);
91 }
92
93 private static void prepare(boolean quitAllowed) {
94 if (sThreadLocal.get() != null) {
95 throw new RuntimeException("Only one Looper may be created per thread");
96 }
97 sThreadLocal.set(new Looper(quitAllowed));
98 }
216 private Looper(boolean quitAllowed) {
217 mQueue = new MessageQueue(quitAllowed);
218 mThread = Thread.currentThread();
219 }
----------------------------------3.Looper.loop()-------------------------
129 public static void loop() {
130 final Looper me = myLooper();
131 if (me == null) {
132 throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
133 }
134 final MessageQueue queue = me.mQueue;
141 for (;;) { //循环looper一直dispatch消息
142 Message msg = queue.next(); // might block
143 if (msg == null) {
144 // No message indicates that the message queue is quitting.
145 return;
146 }
...
164 msg.target.dispatchMessage(msg); //会一直分发消息 dispatchMessage()
...
195 msg.recycleUnchecked();
196 }
197 }
----------------------------------4.Looper.quit()-------------------------
#/frameworks/base/core/java/android/os/Looper.java
267 public void quit() {
268 mQueue.quit(false);
269 }
#/frameworks/base/core/java/android/os/MessageQueue.java
void quit(boolean safe) {
if (!mQuitAllowed) {
throw new IllegalStateException("Main thread not allowed to quit.");
}
synchronized (this) {
if (mQuitting) {
return;
}
mQuitting = true; //退出标志
// We can assume mPtr != 0 because mQuitting was previously false.
nativeWake(mPtr);
}
}
#/frameworks/base/core/java/android/os/MessageQueue.java
Message next() {
for (;;) {
if (nextPollTimeoutMillis != 0) {
Binder.flushPendingCommands();
}
nativePollOnce(ptr, nextPollTimeoutMillis); //idle 的callback Looper.loop-MessageQueue.next--MessageQueue.nativePollOnce
synchronized (this) {
// Process the quit message now that all pending messages have been handled.
if (mQuitting) { //检测到quit()方法改变变量时退出
dispose();
return null;
}
}
}
----------------------------------5.Handler.sendMessage()-------------------------
handler主要1.发送消息sendMessage 2.looper.dispatchMessage之后在处理消息(handleMessage)
#/frameworks/base/core/java/android/os/Handler.java
public final boolean sendMessage(Message msg)
{
return sendMessageDelayed(msg, 0);
}
public final boolean sendMessageDelayed(Message msg, long delayMillis)
{
return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}
public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
MessageQueue queue = mQueue;
if (queue == null) {
RuntimeException e = new RuntimeException(
this + " sendMessageAtTime() called with no mQueue");
Log.w("Looper", e.getMessage(), e);
return false;
}
return enqueueMessage(queue, msg, uptimeMillis); //发送消息到MessageQueue
}
private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
msg.target = this; //msg.target = handler 证明看下段代码
return queue.enqueueMessage(msg, uptimeMillis);
}
#/frameworks/base/core/java/android/os/Message.java
/*package*/ Handler target;
public static Message obtain(Handler h, Runnable callback) {
Message m = obtain();
m.target = h;
m.callback = callback;
return m;
}
#/frameworks/base/core/java/android/os/MessageQueue.java
//Message如链表,添加进去
boolean enqueueMessage(Message msg, long when) {
synchronized (this) {
msg.when = when;
Message p = mMessages;
boolean needWake;
if (p == null || when == 0 || when < p.when) {
// New head, wake up the event queue if blocked.
msg.next = p;
mMessages = msg;
needWake = mBlocked;
} else {
// Inserted within the middle of the queue. Usually we don't have to wake
// up the event queue unless there is a barrier at the head of the queue
// and the message is the earliest asynchronous message in the queue.
needWake = mBlocked && p.target == null && msg.isAsynchronous();
Message prev;
for (;;) {
prev = p;
p = p.next;
if (p == null || when < p.when) {
break;
}
if (needWake && p.isAsynchronous()) {
needWake = false;
}
}
msg.next = p; // invariant: p == prev.next
prev.next = msg;
}
// We can assume mPtr != 0 because mQuitting is false.
if (needWake) {
nativeWake(mPtr);
}
}
return true;
}
----------------------------------6.Handler.handleMessage()-------------------------
在Looper.loop()之后会dispatchMessage分发消息,handler必须重写handleMessage来处理消息
public interface Callback {
public boolean handleMessage(Message msg);
}
/**
* Subclasses must implement this to receive messages.
*/
public void handleMessage(Message msg) {
}
/**
* Handle system messages here.
*/
public void dispatchMessage(Message msg) {
if (msg.callback != null) {
handleCallback(msg);
} else {
if (mCallback != null) {
if (mCallback.handleMessage(msg)) {
return;
}
}
handleMessage(msg);
}
}
推荐阅读
-
AsyncTask陷阱之:Handler,Looper与MessageQueue的详解
-
Handler,Looper,MessageQueue流程梳理
-
Android消息处理机制Looper和Handler详解
-
Android Handler Message 里面的message.what, message.arg1,message.obj,obtainMessage, message.setData的使用
-
Android Studio 之 Android消息机制 之简单Demo --- 使用Handler和Message类来完成消息传递
-
Android异步2:深入详解 Handler+Looper+MessageQueue
-
Android消息机制(3)- Handler和Looper
-
Android Handler 机制 - Looper,Message,MessageQueue
-
handler,message,looper,messagequeue
-
Handler,Looper,Thread,Message,MessageQueue