workflow
工作线程 准备Looper
(app主线程中已经准备好了Looper,可以跳过这一节,直接new Handler)
创建Looper,让Looper运行起来。
- 调用 Looper.prepare() 初始化 Looper
- 启动轮询器 Looper.loop() 进入循环休眠状态,对queue进行轮询。
(保证main函数一直运行,一直存活)主线程looper不答应退出。
- 当消息到达实行时间
- message queue队列 不为空,取出
- message queue队列为空,队列壅闭,
- 等消息队列调用入队 enqueuer Message方法被调用的时候,唤醒队列。从而取出消息停止壅闭。
创建Looper
Activity主线程
app主线程中,可以直接new Handler,跳过这一整章。
prepareMainLooper(),Activity创建时 主线程的Looper是已经准备好了的。
- // frameworks/base/core/java/android/app/ActivityThread.java
- public static void main(String[] args) {
- Looper.prepareMainLooper();
- // ...
- }
- // frameworks/base/core/java/android/os/Looper.java
- @Deprecated
- public static void prepareMainLooper() {
- prepare(false);
- synchronized (Looper.class) {
- if (sMainLooper != null) {
- throw new IllegalStateException("The main Looper has already been prepared.");
- }
- sMainLooper = myLooper();
- }
- }
复制代码 其他环境
在app子线程 / framework中的线程中,想要必要自己做两件事:
- 首先 要创建Looper Looper.prepare
- 之后 让Looper运行起来Looper.loop()死循环
- // Looper.prepare(); // 子线程
- Handler mReportHandler;
- mReportHandler = new Handler() {
- @Override
- public void handleMessage(Message msg) {}
- }
- // Looper.loop(); // 子线程
复制代码 Looper.prepare()
大要流程
Looper.prepare() 首先必要获取当前线程的 Looper
- 假如有当前线程的Looper,获取该 Looper
- 假如没有当前线程的Looper,则实行这一步会自动new一个 Looper 并存到线程本地数据区中。
假如涉及创建,则创建Looper过程中的焦点内容是:
- native层
- 初始化一个 NativeMessageQueue 对象,
- NativeMessageQueue 继承自MessageQueue
- 它持有一个Looper指针
- 初始化 Native 层 Looper 对象
- 将NativeMessageQueue 对象的地址返回给 Java 层。
- java层
- 生存当前线程 Thread 对象。
- 生存创建的 MessageQueue对象(生存有NativeMessageQueue的地址)
java
申请Looper
从本地线程区获取当前线程的 Looper 对象,没有的话,就初始化一个,并存在线程本地数据区中。
- // frameworks/base/core/java/android/os/Looper.java
- public static void prepare() {
- 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));
- }
- // sThreadLocal.get() will return null unless you've called prepare().
- @UnsupportedAppUsage
- static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
复制代码 new Looper
构造函数中:new 一个 Looper 的过程
- 创建了一个 MessageQueue对象
- 获取到了当前线程 Thread 对象。
- // frameworks/base/core/java/android/os/Looper.java
- private Looper(boolean quitAllowed) {
- mQueue = new MessageQueue(quitAllowed); //创建MessageQueue对象
- mThread = Thread.currentThread();
- }
复制代码 MessageQueue初始化
MessageQueue 的初始化过程:
- // frameworks/base/core/java/android/os/MessageQueue.java
- MessageQueue(boolean quitAllowed) {
- mQuitAllowed = quitAllowed;
- mPtr = nativeInit(); // NativeMessageQueue的地址
- // 也包含了对epoll的初始化
- }
- // 调用了 native 方法 nativeInit,对应的 JNI 函数如下
- private native static long nativeInit();
复制代码 native
jni
nativeInit 是一个 Native 方法,对应的 JNI 注册函数如下:
- // frameworks/base/core/jni/android_os_MessageQueue.cpp
- static const JNINativeMethod gMessageQueueMethods[] = {
- /* name, signature, funcPtr */
- { "nativeInit", "()J", (void*)android_os_MessageQueue_nativeInit },
- { "nativeDestroy", "(J)V", (void*)android_os_MessageQueue_nativeDestroy },
- ...
- };
- static struct {
- jfieldID mPtr; // native object attached to the DVM MessageQueue
- jmethodID dispatchEvents;
- } gMessageQueueClassInfo;
- int register_android_os_MessageQueue(JNIEnv* env) {
- int res = RegisterMethodsOrDie(env, "android/os/MessageQueue", gMessageQueueMethods,
- NELEM(gMessageQueueMethods));
- jclass clazz = FindClassOrDie(env, "android/os/MessageQueue");
- gMessageQueueClassInfo.mPtr = GetFieldIDOrDie(env, clazz, "mPtr", "J");
- gMessageQueueClassInfo.dispatchEvents = GetMethodIDOrDie(env, clazz,
- "dispatchEvents", "(II)I");
- return res;
- }
复制代码 NativeMessageQueue
续上前文,native层这部门的焦点内容是
- 初始化一个 NativeMessageQueue 对象,
- NativeMessageQueue 继承自MessageQueue
- 它持有一个Looper指针
- 初始化 Native 层 Looper 对象
- 将NativeMessageQueue 对象的地址返回给 Java 层。
- // frameworks/base/core/jni/android_os_MessageQueue.cpp
- static jlong android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {
- NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
- if (!nativeMessageQueue) {
- jniThrowRuntimeException(env, "Unable to allocate native queue");
- return 0;
- }
- nativeMessageQueue->incStrong(env);
- return reinterpret_cast<jlong>(nativeMessageQueue);
- }
- // frameworks/base/core/jni/android_os_MessageQueue.cpp
- class NativeMessageQueue : public MessageQueue, public LooperCallback {
- private:
- JNIEnv* mPollEnv;
- jobject mPollObj;
- jthrowable mExceptionObj;
- };
- // frameworks/base/core/jni/android_os_MessageQueue.h
- class MessageQueue : public virtual RefBase {
- protected:
- sp<Looper> mLooper;
- };
复制代码- // frameworks/base/core/jni/android_os_MessageQueue.cpp
- // NativeMessageQueue 构造函数
- NativeMessageQueue::NativeMessageQueue() :
- mPollEnv(NULL), mPollObj(NULL), mExceptionObj(NULL) {
- // 初始化 Native 层的 looper
- mLooper = Looper::getForThread();
- if (mLooper == NULL) {
- mLooper = new Looper(false);
- Looper::setForThread(mLooper);
- }
- }
复制代码 Looper.loop()
Looper.loop()在工作线程实行,MSG的消耗,实行,都是在实行该函数的线程中,
(这里的工作线程是指,拥有Looper、处理MSG的线程)
大要流程
- Looper::loop()
- MessageQueue::next
- MessageQueue::nativePollOnce
- ---jni---
- android_os_MessageQueue_nativePollOnce
- NativeMessageQueue::pollOnce
- Looper::pollOnce
- Looper::pollInner
- epoll_wait # 进入阻塞
复制代码 初始化工作完成后,看看 Looper.loop() 方法实行的操纵:
焦点功能就两点:
- 获取 TLS 存储的 Looper 对象
- 进入无限循环,调用 loopOnce 进入休眠状态
- // frameworks/base/core/java/android/os/Looper.java
- public static void loop() {
- // 获取 TLS 存储的 Looper 对象
- final Looper me = myLooper();
- // 进入无限循环,
- for (;;) {
- // MessageQueue.next() 获取 Message,可能阻塞
- Message msg = queue.next(); // might block
- // 分发消息,调用 handler 中的回调函数
- msg.target.dispatchMessage(msg);
- }
- }
复制代码 java
获取Looper
获取 TLS 存储的 Looper 对象很好理解。
- // frameworks/base/core/java/android/os/Looper.java
- public static void loop() {
- // 获取 TLS 存储的 Looper 对象
- final Looper me = myLooper();
- me.mInLoop = true;
- //...
- }
- public static @Nullable Looper myLooper() {
- return sThreadLocal.get();
- }
- // sThreadLocal.get() will return null unless you've called prepare().
- @UnsupportedAppUsage
- static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
复制代码 获取msg,处理msg
获取msg、处理 msg 的过程,原先被封装在 loop::loopOnce 中。最终都是调用了MessageQueue.next()
详细,见下一章节。
Looper.loop()
- // frameworks/base/core/java/android/os/Looper.java
- public static void loop() {
- // 进入无限循环,
- for (;;) {
- // MessageQueue.next() 获取 Message,可能阻塞
- Message msg = queue.next(); // might block
- // 分发消息,调用 handler 中的回调函数
- msg.target.dispatchMessage(msg);
- }
- }
复制代码 Looper.loopOnce (已过时)
现实上,Looper.loopOnce是从MessageQueue中取出一个msg并实行。
但在使用中,无限循环内Looper.loopOnce被多次调用。因此,现实上也不必要这个封装了。直接使用 MessageQueue.next()获取msg,和 Handler .dispatchMessage 处理msg。
调用 loopOnce 进入休眠状态
焦点流程
- 通过 MessageQueue 的 next 方法拿到一个 Message,
这里可能会壅闭休眠
- 通过 dispatchMessage 调用 Handler 中的回调方法
- // frameworks/base/core/java/android/os/Looper.java
- private static boolean loopOnce(final Looper me,
- final long ident, final int thresholdOverride) {
- // 获取 Message,可能阻塞
- Message msg = me.mQueue.next();
- if (msg == null) {}
- // ...
- try {
- //分发消息,调用 handler 中的回调函数
- msg.target.dispatchMessage(msg);
- if (observer != null) {
- observer.messageDispatched(token, msg);
- }
- dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
- // ...
- msg.recycleUnchecked();
- return true;
- }
复制代码 获取msg 休眠
通过 MessageQueue 的 next 方法拿到一个 Message,这里可能会壅闭休眠。
- // frameworks/base/core/java/android/os/Looper.java
- public static void loop() {
- // ...
- // 进入无限循环,
- for (;;) {
- // MessageQueue.next() 获取 Message,可能阻塞
- Message msg = queue.next(); // might block
- // 分发消息,调用 handler 中的回调函数
- // 但由于阻塞,这里会在 主线程2 唤醒后才调用
- // frameworks/base/core/java/android/os/Handler.java
- // public void dispatchMessage(@NonNull Message msg) {
- msg.target.dispatchMessage(msg);
- }
- }
复制代码 MessageQueue.next()
调用 nativePollOnce 陷入 Native 层,进入休眠状态,
- // frameworks/base/core/java/android/os/MessageQueue.java
- Message next() {
- final long ptr = mPtr; // 这个指向 NativeMessageQueue 还记得吗
- for (;;) {
- // 陷入 Native 层,进入休眠状态
- nativePollOnce(ptr, nextPollTimeoutMillis);
- //......
- }
- }
- private native void nativePollOnce(long ptr, int timeoutMillis);
复制代码 native
jni
nativePollOnce 是一个 Native 方法,对应的 JNI 注册函数如下:
- // frameworks/base/core/jni/android_os_MessageQueue.cpp
- static const JNINativeMethod gMessageQueueMethods[] = {
- /* name, signature, funcPtr */
- { "nativeInit", "()J", (void*)android_os_MessageQueue_nativeInit },
- // ...
- { "nativePollOnce", "(JI)V", (void*)android_os_MessageQueue_nativePollOnce },
- // ...
- };
复制代码- static struct {
- jfieldID mPtr; // native object attached to the DVM MessageQueue
- jmethodID dispatchEvents;
- } gMessageQueueClassInfo;
- int register_android_os_MessageQueue(JNIEnv* env) {
- int res = RegisterMethodsOrDie(env, "android/os/MessageQueue", gMessageQueueMethods,
- NELEM(gMessageQueueMethods));
- jclass clazz = FindClassOrDie(env, "android/os/MessageQueue");
- gMessageQueueClassInfo.mPtr = GetFieldIDOrDie(env, clazz, "mPtr", "J");
- gMessageQueueClassInfo.dispatchEvents = GetMethodIDOrDie(env, clazz,
- "dispatchEvents", "(II)I");
- return res;
- }
复制代码 native
通过传入的指针,获取到 Native 层的 NativeMessageQueue 对象,接着调用 NativeMessageQueue 对象的 pollOnce 方法。
- // frameworks/base/core/jni/android_os_MessageQueue.cpp
- static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
- jlong ptr, jint timeoutMillis) {
- NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
- nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
- }
复制代码 Native 层 Looper 的 pollOnce 函数,pollOnce 内部重要是调用 epoll_wait 来进入休眠状态。
- // frameworks/base/core/jni/android_os_MessageQueue.cpp
- void NativeMessageQueue::pollOnce(JNIEnv* env, jobject pollObj, int timeoutMillis) {
- // ...
- // 内部调用 epoll_wait 阻塞
- mLooper->pollOnce(timeoutMillis);
- // ...
- }
复制代码 上面已经调用 Native 层 Looper::pollOnce 函数,从而调用 epoll_wait 来进入休眠状态。
- // frameworks/core/core/libutils/Looper.cpp
- // system/core/libutils/Looper.cpp
- int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
- for (;;) {
- while (mResponseIndex < mResponses.size()) {
- const Response& response = mResponses.itemAt(mResponseIndex++);
- if (ident >= 0) {... return ident;}
- }
- if (result != 0) {return result;}
- // 如果没有 在 Vector<Response> mResponses; 其中有 sp<LooperCallback> callback;
- // 则进入下面的休眠状态
- result = pollInner(timeoutMillis);
- }
- }
复制代码- // system/core/libutils/Looper.cpp
- int Looper::pollInner(int timeoutMillis) {
- // ...
- int eventCount = epoll_wait(epollfd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
复制代码 pollOnce 的详细代码分析可以参考上述Looper - native - pollAll 部门,这里不再重复。
至此,我们的线程就下 cpu,进入休眠状态。
别的线程 发送msg
大要来说
初始化一个 Handler 对象,再传入 msg。发送消息大致三步:
- 初始化一个 Handler 对象,覆写 Handler 的 handleMessage 方法
- 构建一个 Message 对象
- 通过 Handler 的 sendMessage 方法发送消息
后续,会实行 handleMessage
准备Handler
在使用 Looper 的线程中通常会初始化一个 Handler 对象,重写其handleMessage方法。
构造函数
Handler时,必要指定 Looper 意味着于此同时确定了对应的MessageQueue。
- // frameworks/base/core/java/android/os/Handler.java
- public Handler(@NonNull Looper looper) {
- this(looper, null, false);
- }
- public Handler(@NonNull Looper looper, @Nullable Callback callback) {
- this(looper, callback, false);
- }
- public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async,
- boolean shared) {
- mLooper = looper;
- mQueue = looper.mQueue;
- mCallback = callback;
- mAsynchronous = async;
- mIsShared = shared;
- }
复制代码 重写 handleMessage
当 Handler.sendMessage 方法调用时,(无论是本线程的Handler还是别的线程的Handler),在MessageQueue中排队后都会调用该Handeler的handleMessage方法。
- // new 一个 Handler,覆写 handleMessage 方法
- mHandler = new Handler() {
- public void handleMessage(Message msg) {
- //定义消息处理逻辑.
- }
- };
复制代码- // 典型的关于Handler/Looper的线程
- class LooperThread extends Thread {
- public Handler mHandler;
- public void run() {
- Looper.prepare(); // 子线程需要,主线程不需要
- mHandler = new Handler() {
- public void handleMessage(Message msg) {
- //定义消息处理逻辑.
- Message msg = Message.obtain();
- }
- };
- Looper.loop(); // 子线程需要,主线程不需要
- }
- }
复制代码 重要的成员变量
Handler 初始化过程中,要对 Handler 中有两个重要变量进行赋值:
- mLooper:当前线程的 Looper
- mQueue: 当前进程的 MessageQueue
- public Handler() {
- this(null, false);
- }
- public Handler(@Nullable Callback callback, boolean async) {
- // 当前线程的 Looper 对象
- mLooper = Looper.myLooper();
- if (mLooper == null) {
- throw new RuntimeException(
- "Can't create handler inside thread " + Thread.currentThread()
- + " that has not called Looper.prepare()");
- }
- // 当前进程的 MessageQueue
- mQueue = mLooper.mQueue;
- mCallback = callback;
- mAsynchronous = async;
- }
复制代码 Handler发送Msg
准备Msg
做好以上的准备工作后,准备Message
- // 构建一个 Message
- Message msg = new Message();
- // 获知遵循享元模式:
- Message msg = Message.obtain();
- msg.what = 2;
- msg.obj = "B";
- Message msg = mReportHandler.obtainMessage(MSG_SWITCH_TO_SDR_MEMC);
- mReportHandler.sendMessage(message);
- // 通过 Handler 的 sendMessage 方法发送消息
- mHandler.sendMessage(msg);
复制代码 我们先看看 Message 的初始化过程:
- // frameworks/base/core/java/android/os/Message.java
- public static Message obtain() {
- synchronized (sPoolSync) {
- if (sPool != null) {
- Message m = sPool;
- sPool = m.next;
- m.next = null;
- m.flags = 0; // clear in-use flag
- sPoolSize--;
- return m;
- }
- }
- return new Message();
- }
复制代码 从缓存 sPool 内里取 Message,假如没有的话就 new 一个 Message。
Handelr发送msg
重要函数
子线程 Handler为了发送MSG,归根结底,都是使用了 入队MSG Handler.enqueueMessage()
Handler::sendMessage
mHandler.sendMessage(msg) 内部继续对传入的 Message 进行进一步赋值。例如:把handler的this指针,赋值给了 msg 的 target 成员,这样调用时就知道应该实行哪一个Handler对应的函数了。
- // frameworks/base/core/java/android/os/Handler.java
- public final boolean sendMessage(@NonNull Message msg) { ... }
- public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
- MessageQueue queue = mQueue;
- return enqueueMessage(queue, msg, uptimeMillis);
- }
- private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg, long uptimeMillis) {
- // 注意这里
- msg.target = this; // 把handler的this指针,赋值给了msg的 target 成员
- msg.workSourceUid = ThreadLocalWorkSource.getUid();
- // 最终调用到 MessageQueue 的 enqueueMessage 方法
- return queue.enqueueMessage(msg, uptimeMillis);
- }
复制代码 MessageQueue::enqueueMessage
MessageQueue.enqueueMessage 代码有点长,焦点逻辑:
- 把 Message 插入 mMessages 链表
- 调用 native 方法 nativeWake 唤醒 native 层的 epoll
- // frameworks/base/core/java/android/os/MessageQueue.java
- boolean enqueueMessage(Message msg, long when) {
- // 添加msg到链表
- Message p = mMessages;
- msg.next = p;
- mMessages = msg;
- // We can assume mPtr != 0 because mQuitting is false.
- // 唤醒Looper,进入native
- if (needWake) {
- nativeWake(mPtr);
- }
复制代码 nativeWake
nativeWake 最终会调用 native 层 mLooper 的 wake 函数,
- private native static void nativeWake(long ptr);
复制代码 向 eventfd 写入数据,唤醒与 eventfd 绑定的 epoll。
- // nativeWake 对应的 JNI 函数
- static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr) {
- NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
- nativeMessageQueue->wake();
- }
- void NativeMessageQueue::wake() {
- mLooper->wake();
- }
- // eventfd 写数据,唤醒 epoll
- void Looper::wake() {
- // 大体就是
- write(mWakeEventFd.get(), &inc, sizeof(uint64_t));
- }
复制代码- // 这个mWakeEventFd就是epoll关注的句柄之一
- void Looper::rebuildEpollLocked() {
- struct epoll_event eventItem;
- memset(& eventItem, 0, sizeof(epoll_event));
- eventItem.data.fd = mWakeEventFd.get();
复制代码- // 之前陷入阻塞,也是和eventItems有关
- int Looper::pollInner(int timeoutMillis) {
- // ...
- epoll_wait(epollfd.get(), eventItems, EPOLL_MAX_EVENTS, timeoutMillis);
复制代码 接下来我们就来看看 epoll 唤醒以后的流程。
(仅作了解) 工作线程中实行
以下仅作了解,一样平常来说使用时不必要关心。
之前我们 或被动,或主动的在一个/一些线程中调用了 Looper::loop()。
在线程(一样平常是主线程)中实行Looper.loop(),则这个线程就是“工作线程”。可以认为是MSG的消耗者:全部的MSG的消耗,实行都是在该线程中,
- 调用了 Looper::loop() 的线程,会从进程的MessageQueue中取出、处理MSG,并实行Hanlder的重载。
- 因为 MessageQueue 是线程安全的,所以可以有多个线程调用 Looper::loop(),这些线程并行的处理Hanlder。
唤醒
native
Looper::pollInner 解除壅闭后,一路上函数调用栈恢复。相对应的,Java 层的 next 方法被唤醒。
- Looper::loop()
- MessageQueue::next
- MessageQueue::nativePollOnce
- ---jni---
- android_os_MessageQueue_nativePollOnce
- NativeMessageQueue::pollOnce
- Looper::pollOnce
- Looper::pollInner
- epoll_wait # 解除阻塞
复制代码 java
唤醒后,一样平常的流程就是从 mMessages 中找个符合的 message 返回,
MessageQueue::next()
- // frameworks/base/core/java/android/os/MessageQueue.java
- public final class MessageQueue {
- Message next() {
- // ...
- for (;;) {
- // 在这个位置陷入 Native 层,进入休眠状态
- // 所以也是从这个位置唤醒
- nativePollOnce(ptr, nextPollTimeoutMillis);
- // 从 mMessages 链表中选取一个合适的 message 返回
- synchronized (this) {
- // Try to retrieve the next message. Return if found.
- final long now = SystemClock.uptimeMillis();
- Message prevMsg = null;
- Message msg = mMessages;
复制代码 Looper::loop
再继续返回后进入上一层
- // frameworks/base/core/java/android/os/Looper.java
- // frameworks/base/core/java/android/os/Looper.java
- public static void loop() {
- // 进入无限循环,
- for (;;) {
- // 从这里恢复阻塞
- Message msg = queue.next(); // MessageQueue.next() 获取 Message
- // 分发消息,调用 handler 中的回调函数
- msg.target.dispatchMessage(msg);
- }
- }
复制代码 代码很多,焦点的流程只有两点:
- next() 处返回一个符合的 message
- 通过 msg.target.dispatchMessage(msg) 调用 handler 中的回调
至此,整个 Looper 流程就走完了。
唤醒后
- Looper.loop() # 唤醒后执行如下步骤
- MessageQueue.next() # 获取msg
- Handler.dispatchMessage # 处理msg
- Handler.handleMessage
复制代码 获取MSG
Looper不停的调用,从消息队列中获取消息使用for循环
- // frameworks/base/core/java/android/os/Looper.java
- /**
- * Run the message queue in this thread. Be sure to call
- * {@link #quit()} to end the loop.
- */
- public static void loop() {
- final Looper me = myLooper();
- for (;;) {
- // MessageQueue.next() 获取 Message,可能阻塞
- Message msg = queue.next(); // might block
- if (msg == null) {
- // No message indicates that the message queue is quitting.
- return;
- }
- // 处理MSG,下文会介绍
复制代码 处理MSG
主线程处理,之前传入MessageQueue的MSG,在主线程中实行。
- // frameworks/base/core/java/android/os/Looper.java
- public static void loop() {
- // ...
- // 由于阻塞,在 主线程唤醒后 开始处理获得的msg
- // 分发消息,调用 handler 中的回调函数
- msg.target.dispatchMessage(msg);
- }
- }
复制代码 Message持有Handler,Handler持有Callback。
- // frameworks/base/core/java/android/os/Message.java
- public final class Message implements Parcelable {
- @UnsupportedAppUsage
- // 这个msg.target就是Handler的this指针,是其他线程初始化Msg时自动填入
- /*package*/ Handler target;
复制代码- // frameworks/base/core/java/android/os/Handler.java
- public class Handler {
- public void handleMessage(@NonNull Message msg) {}
- final Callback mCallback;
- public interface Callback {
- boolean handleMessage(@NonNull Message msg);
- }
- }
复制代码 Handler::dispatchMessage
Handler的方法 handleMessage dispatchMessage 等,最终会调用到以下方法
- // frameworks/base/core/java/android/os/Handler.java
- /**
- * Handle system messages here.
- */
- public void dispatchMessage(@NonNull Message msg) {
- if (msg.callback != null) {
- handleCallback(msg); // 1 Runnable run
- } else {
- if (mCallback != null) { // 2 final Callback mCallback;
- if (mCallback.handleMessage(msg)) {
- return;
- }
- }
- handleMessage(msg);
- }
- }
- private static void handleCallback(Message message) {
- message.callback.run(); // 1 Runnable callback;
- }
- public Handler(@Nullable Callback callback, boolean async) {
- mLooper = Looper.myLooper();
- mQueue = mLooper.mQueue;
- mCallback = callback; // 2 执行这里的 handleMessage
- }
- public void handleMessage(@NonNull Message msg) { // 3 执行子类的重载(通常说的就是这里)
- }
复制代码 Handler::handleMessage
这也是初始化Handler时,必要重写 handleMessage 的原因
在使用 Looper 的线程中通常会初始化一个 Handler 对象:
- // new 一个 Handler,覆写 handleMessage 方法
- mHandler = new Handler() {
- public void handleMessage(Message msg) {
- //定义消息处理逻辑.
- }
- };
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |