安卓根本组件Looper - 03 java层面的分析

打印 上一主题 下一主题

主题 862|帖子 862|积分 2586

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是已经准备好了的。
  1. // frameworks/base/core/java/android/app/ActivityThread.java
  2. public static void main(String[] args) {
  3.     Looper.prepareMainLooper();
  4.     // ...
  5. }
  6. // frameworks/base/core/java/android/os/Looper.java
  7. @Deprecated
  8. public static void prepareMainLooper() {
  9.     prepare(false);
  10.     synchronized (Looper.class) {
  11.         if (sMainLooper != null) {
  12.             throw new IllegalStateException("The main Looper has already been prepared.");
  13.         }
  14.         sMainLooper = myLooper();
  15.     }
  16. }
复制代码
其他环境

在app子线程 / framework中的线程中,想要必要自己做两件事:


  • 首先 要创建Looper Looper.prepare
  • 之后 让Looper运行起来Looper.loop()死循环
  1. // Looper.prepare();  // 子线程
  2. Handler mReportHandler;
  3. mReportHandler = new Handler() {
  4.     @Override
  5.     public void handleMessage(Message msg) {}
  6. }
  7. // 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 对象,没有的话,就初始化一个,并存在线程本地数据区中。
  1. // frameworks/base/core/java/android/os/Looper.java
  2. public static void prepare() {
  3.     prepare(true);
  4. }
  5. private static void prepare(boolean quitAllowed) {
  6.     if (sThreadLocal.get() != null) {
  7.         throw new RuntimeException("Only one Looper may be created per thread");
  8.     }
  9.     sThreadLocal.set(new Looper(quitAllowed));
  10. }
  11. // sThreadLocal.get() will return null unless you've called prepare().
  12. @UnsupportedAppUsage
  13. static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
复制代码
new Looper

构造函数中:new 一个 Looper 的过程


  • 创建了一个 MessageQueue对象
  • 获取到了当前线程 Thread 对象。
  1. // frameworks/base/core/java/android/os/Looper.java
  2. private Looper(boolean quitAllowed) {
  3.     mQueue = new MessageQueue(quitAllowed);  //创建MessageQueue对象
  4.     mThread = Thread.currentThread();
  5. }
复制代码
MessageQueue初始化

MessageQueue 的初始化过程:
  1. // frameworks/base/core/java/android/os/MessageQueue.java
  2. MessageQueue(boolean quitAllowed) {
  3.     mQuitAllowed = quitAllowed;
  4.     mPtr = nativeInit();        // NativeMessageQueue的地址
  5.                                                     // 也包含了对epoll的初始化
  6. }
  7. // 调用了 native 方法 nativeInit,对应的 JNI 函数如下
  8. private native static long nativeInit();
复制代码
native

jni

nativeInit 是一个 Native 方法,对应的 JNI 注册函数如下:
  1. // frameworks/base/core/jni/android_os_MessageQueue.cpp
  2. static const JNINativeMethod gMessageQueueMethods[] = {
  3.     /* name, signature, funcPtr */
  4.     { "nativeInit", "()J", (void*)android_os_MessageQueue_nativeInit },
  5.     { "nativeDestroy", "(J)V", (void*)android_os_MessageQueue_nativeDestroy },
  6.     ...
  7. };
  8. static struct {
  9.     jfieldID mPtr;   // native object attached to the DVM MessageQueue
  10.     jmethodID dispatchEvents;
  11. } gMessageQueueClassInfo;
  12. int register_android_os_MessageQueue(JNIEnv* env) {
  13.     int res = RegisterMethodsOrDie(env, "android/os/MessageQueue", gMessageQueueMethods,
  14.                                    NELEM(gMessageQueueMethods));
  15.     jclass clazz = FindClassOrDie(env, "android/os/MessageQueue");
  16.     gMessageQueueClassInfo.mPtr = GetFieldIDOrDie(env, clazz, "mPtr", "J");
  17.     gMessageQueueClassInfo.dispatchEvents = GetMethodIDOrDie(env, clazz,
  18.             "dispatchEvents", "(II)I");
  19.     return res;
  20. }
复制代码
NativeMessageQueue

续上前文,native层这部门的焦点内容是


  • 初始化一个 NativeMessageQueue 对象,

    • NativeMessageQueue 继承自MessageQueue
    • 它持有一个Looper指针

  • 初始化 Native 层 Looper 对象
  • 将NativeMessageQueue 对象的地址返回给 Java 层。
  1. // frameworks/base/core/jni/android_os_MessageQueue.cpp
  2. static jlong android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {
  3.     NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
  4.     if (!nativeMessageQueue) {
  5.         jniThrowRuntimeException(env, "Unable to allocate native queue");
  6.         return 0;
  7.     }
  8.     nativeMessageQueue->incStrong(env);
  9.     return reinterpret_cast<jlong>(nativeMessageQueue);
  10. }
  11. // frameworks/base/core/jni/android_os_MessageQueue.cpp
  12. class NativeMessageQueue : public MessageQueue, public LooperCallback {
  13. private:
  14.     JNIEnv* mPollEnv;
  15.     jobject mPollObj;
  16.     jthrowable mExceptionObj;
  17. };
  18. // frameworks/base/core/jni/android_os_MessageQueue.h
  19. class MessageQueue : public virtual RefBase {
  20. protected:
  21.     sp<Looper> mLooper;
  22. };
复制代码
  1. // frameworks/base/core/jni/android_os_MessageQueue.cpp
  2. // NativeMessageQueue 构造函数
  3. NativeMessageQueue::NativeMessageQueue() :
  4.         mPollEnv(NULL), mPollObj(NULL), mExceptionObj(NULL) {
  5.     // 初始化 Native 层的 looper
  6.     mLooper = Looper::getForThread();
  7.     if (mLooper == NULL) {
  8.         mLooper = new Looper(false);
  9.         Looper::setForThread(mLooper);
  10.     }
  11. }
复制代码
Looper.loop()

Looper.loop()在工作线程实行,MSG的消耗,实行,都是在实行该函数的线程中,
(这里的工作线程是指,拥有Looper、处理MSG的线程)
大要流程

  1. Looper::loop()
  2.     MessageQueue::next
  3.         MessageQueue::nativePollOnce
  4. ---jni---
  5. android_os_MessageQueue_nativePollOnce
  6.         NativeMessageQueue::pollOnce
  7.         Looper::pollOnce
  8.                 Looper::pollInner
  9.                         epoll_wait # 进入阻塞
复制代码
初始化工作完成后,看看 Looper.loop() 方法实行的操纵:
焦点功能就两点:


  • 获取 TLS 存储的 Looper 对象
  • 进入无限循环,调用 loopOnce 进入休眠状态
  1. // frameworks/base/core/java/android/os/Looper.java
  2. public static void loop() {
  3.     // 获取 TLS 存储的 Looper 对象
  4.     final Looper me = myLooper();
  5.     // 进入无限循环,
  6.     for (;;) {
  7.         // MessageQueue.next() 获取 Message,可能阻塞
  8.         Message msg = queue.next(); // might block
  9.         // 分发消息,调用 handler 中的回调函数
  10.         msg.target.dispatchMessage(msg);
  11.     }
  12. }
复制代码
java

获取Looper

获取 TLS 存储的 Looper 对象很好理解。
  1. // frameworks/base/core/java/android/os/Looper.java
  2. public static void loop() {
  3.     // 获取 TLS 存储的 Looper 对象
  4.     final Looper me = myLooper();
  5.     me.mInLoop = true;
  6.         //...
  7. }
  8. public static @Nullable Looper myLooper() {
  9.     return sThreadLocal.get();
  10. }
  11. // sThreadLocal.get() will return null unless you've called prepare().
  12. @UnsupportedAppUsage
  13. static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
复制代码
获取msg,处理msg

获取msg、处理 msg 的过程,原先被封装在 loop::loopOnce 中。最终都是调用了MessageQueue.next()
详细,见下一章节。
Looper.loop()

  1. // frameworks/base/core/java/android/os/Looper.java
  2. public static void loop() {
  3.     // 进入无限循环,
  4.     for (;;) {
  5.         // MessageQueue.next() 获取 Message,可能阻塞
  6.         Message msg = queue.next(); // might block
  7.         // 分发消息,调用 handler 中的回调函数
  8.         msg.target.dispatchMessage(msg);
  9.     }
  10. }
复制代码
Looper.loopOnce (已过时)

现实上,Looper.loopOnce是从MessageQueue中取出一个msg并实行。
但在使用中,无限循环内Looper.loopOnce被多次调用。因此,现实上也不必要这个封装了。直接使用 MessageQueue.next()获取msg,和 Handler .dispatchMessage 处理msg。
调用 loopOnce 进入休眠状态
焦点流程


  • 通过 MessageQueue 的 next 方法拿到一个 Message,
    这里可能会壅闭休眠
  • 通过 dispatchMessage 调用 Handler 中的回调方法
  1. // frameworks/base/core/java/android/os/Looper.java
  2. private static boolean loopOnce(final Looper me,
  3.                                 final long ident, final int thresholdOverride) {
  4.     // 获取 Message,可能阻塞
  5.     Message msg = me.mQueue.next();
  6.     if (msg == null) {}
  7.         // ...
  8.     try {
  9.         //分发消息,调用 handler 中的回调函数
  10.         msg.target.dispatchMessage(msg);
  11.         if (observer != null) {
  12.             observer.messageDispatched(token, msg);
  13.         }
  14.         dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
  15.                 // ...
  16.     msg.recycleUnchecked();
  17.     return true;
  18. }   
复制代码
获取msg 休眠

通过 MessageQueue 的 next 方法拿到一个 Message,这里可能会壅闭休眠。
  1. // frameworks/base/core/java/android/os/Looper.java
  2. public static void loop() {
  3.     // ...
  4.     // 进入无限循环,
  5.     for (;;) {
  6.         // MessageQueue.next() 获取 Message,可能阻塞
  7.         Message msg = queue.next(); // might block
  8.         // 分发消息,调用 handler 中的回调函数
  9.         // 但由于阻塞,这里会在 主线程2 唤醒后才调用
  10.         // frameworks/base/core/java/android/os/Handler.java
  11.         // public void dispatchMessage(@NonNull Message msg) {
  12.         msg.target.dispatchMessage(msg);
  13.     }
  14. }
复制代码
MessageQueue.next()
调用 nativePollOnce 陷入 Native 层,进入休眠状态,
  1. // frameworks/base/core/java/android/os/MessageQueue.java
  2. Message next() {
  3.     final long ptr = mPtr;        // 这个指向 NativeMessageQueue 还记得吗
  4.     for (;;) {
  5.         // 陷入 Native 层,进入休眠状态
  6.         nativePollOnce(ptr, nextPollTimeoutMillis);
  7.         //......
  8.     }
  9. }
  10. private native void nativePollOnce(long ptr, int timeoutMillis);
复制代码
native

jni

nativePollOnce 是一个 Native 方法,对应的 JNI 注册函数如下:
  1. // frameworks/base/core/jni/android_os_MessageQueue.cpp
  2. static const JNINativeMethod gMessageQueueMethods[] = {
  3.     /* name, signature, funcPtr */
  4.     { "nativeInit", "()J", (void*)android_os_MessageQueue_nativeInit },
  5.     // ...
  6.     { "nativePollOnce", "(JI)V", (void*)android_os_MessageQueue_nativePollOnce },
  7.     // ...
  8. };
复制代码
  1. static struct {
  2.     jfieldID mPtr;   // native object attached to the DVM MessageQueue
  3.     jmethodID dispatchEvents;
  4. } gMessageQueueClassInfo;
  5. int register_android_os_MessageQueue(JNIEnv* env) {
  6.     int res = RegisterMethodsOrDie(env, "android/os/MessageQueue", gMessageQueueMethods,
  7.                                    NELEM(gMessageQueueMethods));
  8.     jclass clazz = FindClassOrDie(env, "android/os/MessageQueue");
  9.     gMessageQueueClassInfo.mPtr = GetFieldIDOrDie(env, clazz, "mPtr", "J");
  10.     gMessageQueueClassInfo.dispatchEvents = GetMethodIDOrDie(env, clazz,
  11.             "dispatchEvents", "(II)I");
  12.     return res;
  13. }
复制代码
native

通过传入的指针,获取到 Native 层的 NativeMessageQueue 对象,接着调用 NativeMessageQueue 对象的 pollOnce 方法。
  1. // frameworks/base/core/jni/android_os_MessageQueue.cpp
  2. static void android_os_MessageQueue_nativePollOnce(JNIEnv* env, jobject obj,
  3.         jlong ptr, jint timeoutMillis) {
  4.     NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
  5.     nativeMessageQueue->pollOnce(env, obj, timeoutMillis);
  6. }
复制代码
Native 层 Looper 的 pollOnce 函数,pollOnce 内部重要是调用 epoll_wait 来进入休眠状态。
  1. // frameworks/base/core/jni/android_os_MessageQueue.cpp
  2. void NativeMessageQueue::pollOnce(JNIEnv* env, jobject pollObj, int timeoutMillis) {
  3.         // ...
  4.     // 内部调用 epoll_wait 阻塞
  5.     mLooper->pollOnce(timeoutMillis);
  6.         // ...
  7. }
复制代码
上面已经调用 Native 层 Looper::pollOnce 函数,从而调用 epoll_wait 来进入休眠状态。
  1. // frameworks/core/core/libutils/Looper.cpp
  2. // system/core/libutils/Looper.cpp
  3. int Looper::pollOnce(int timeoutMillis, int* outFd, int* outEvents, void** outData) {
  4.     for (;;) {
  5.             while (mResponseIndex < mResponses.size()) {
  6.             const Response& response = mResponses.itemAt(mResponseIndex++);
  7.             if (ident >= 0) {... return ident;}
  8.         }
  9.         if (result != 0) {return result;}
  10.         // 如果没有 在 Vector<Response> mResponses; 其中有 sp<LooperCallback> callback;
  11.         // 则进入下面的休眠状态
  12.         result = pollInner(timeoutMillis);
  13.     }
  14. }
复制代码
  1. // system/core/libutils/Looper.cpp
  2. int Looper::pollInner(int timeoutMillis) {
  3.     // ...
  4.     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。
  1. // frameworks/base/core/java/android/os/Handler.java
  2.     public Handler(@NonNull Looper looper) {
  3.         this(looper, null, false);
  4.     }
  5.     public Handler(@NonNull Looper looper, @Nullable Callback callback) {
  6.         this(looper, callback, false);
  7.     }
  8.     public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async,
  9.             boolean shared) {
  10.         mLooper = looper;
  11.         mQueue = looper.mQueue;
  12.         mCallback = callback;
  13.         mAsynchronous = async;
  14.         mIsShared = shared;
  15.     }
复制代码
重写 handleMessage

当 Handler.sendMessage 方法调用时,(无论是本线程的Handler还是别的线程的Handler),在MessageQueue中排队后都会调用该Handeler的handleMessage方法。
  1. // new 一个 Handler,覆写 handleMessage 方法
  2. mHandler = new Handler() {  
  3.     public void handleMessage(Message msg) {
  4.         //定义消息处理逻辑.
  5.     }
  6. };
复制代码
  1. // 典型的关于Handler/Looper的线程
  2. class LooperThread extends Thread {
  3.     public Handler mHandler;
  4.     public void run() {
  5.         Looper.prepare();   // 子线程需要,主线程不需要
  6.         mHandler = new Handler() {  
  7.             public void handleMessage(Message msg) {
  8.                 //定义消息处理逻辑.
  9.                 Message msg = Message.obtain();
  10.             }
  11.         };
  12.         Looper.loop();   // 子线程需要,主线程不需要
  13.     }
  14. }
复制代码
重要的成员变量

Handler 初始化过程中,要对 Handler 中有两个重要变量进行赋值:


  • mLooper:当前线程的 Looper
  • mQueue: 当前进程的 MessageQueue
  1. public Handler() {
  2.     this(null, false);
  3. }
  4. public Handler(@Nullable Callback callback, boolean async) {
  5.     // 当前线程的 Looper 对象
  6.     mLooper = Looper.myLooper();
  7.     if (mLooper == null) {
  8.         throw new RuntimeException(
  9.             "Can't create handler inside thread " + Thread.currentThread()
  10.             + " that has not called Looper.prepare()");
  11.     }
  12.     // 当前进程的 MessageQueue
  13.     mQueue = mLooper.mQueue;
  14.     mCallback = callback;
  15.     mAsynchronous = async;
  16. }
复制代码
Handler发送Msg

准备Msg

做好以上的准备工作后,准备Message
  1. // 构建一个 Message
  2. Message msg = new Message();
  3. // 获知遵循享元模式:
  4. Message msg = Message.obtain();
  5. msg.what = 2;
  6. msg.obj = "B";
  7. Message msg = mReportHandler.obtainMessage(MSG_SWITCH_TO_SDR_MEMC);
  8. mReportHandler.sendMessage(message);
  9. // 通过 Handler 的 sendMessage 方法发送消息
  10. mHandler.sendMessage(msg);
复制代码
我们先看看 Message 的初始化过程:
  1. // frameworks/base/core/java/android/os/Message.java
  2. public static Message obtain() {
  3.     synchronized (sPoolSync) {
  4.         if (sPool != null) {
  5.             Message m = sPool;
  6.             sPool = m.next;
  7.             m.next = null;
  8.             m.flags = 0; // clear in-use flag
  9.             sPoolSize--;
  10.             return m;
  11.         }
  12.     }
  13.     return new Message();
  14. }
复制代码
从缓存 sPool 内里取 Message,假如没有的话就 new 一个 Message。
Handelr发送msg

重要函数

子线程 Handler为了发送MSG,归根结底,都是使用了 入队MSG Handler.enqueueMessage()

Handler::sendMessage

mHandler.sendMessage(msg) 内部继续对传入的 Message 进行进一步赋值。例如:把handler的this指针,赋值给了 msg 的 target 成员,这样调用时就知道应该实行哪一个Handler对应的函数了
  1. // frameworks/base/core/java/android/os/Handler.java
  2. public final boolean sendMessage(@NonNull Message msg) { ... }
  3. public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
  4.     MessageQueue queue = mQueue;
  5.     return enqueueMessage(queue, msg, uptimeMillis);
  6. }
  7. private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg, long uptimeMillis) {
  8.     // 注意这里
  9.     msg.target = this;  // 把handler的this指针,赋值给了msg的 target 成员
  10.     msg.workSourceUid = ThreadLocalWorkSource.getUid();
  11.         // 最终调用到 MessageQueue 的 enqueueMessage 方法
  12.     return queue.enqueueMessage(msg, uptimeMillis);
  13. }
复制代码
MessageQueue::enqueueMessage

MessageQueue.enqueueMessage 代码有点长,焦点逻辑:


  • 把 Message 插入 mMessages 链表
  • 调用 native 方法 nativeWake 唤醒 native 层的 epoll
  1. // frameworks/base/core/java/android/os/MessageQueue.java
  2. boolean enqueueMessage(Message msg, long when) {
  3.         // 添加msg到链表
  4.         Message p = mMessages;
  5.     msg.next = p;
  6.     mMessages = msg;
  7.     // We can assume mPtr != 0 because mQuitting is false.
  8.     // 唤醒Looper,进入native
  9.     if (needWake) {
  10.         nativeWake(mPtr);
  11.     }
复制代码
nativeWake

nativeWake 最终会调用 native 层 mLooper 的 wake 函数,
  1. private native static void nativeWake(long ptr);
复制代码
向 eventfd 写入数据,唤醒与 eventfd 绑定的 epoll。
  1. // nativeWake 对应的 JNI 函数
  2. static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr) {
  3.     NativeMessageQueue* nativeMessageQueue = reinterpret_cast<NativeMessageQueue*>(ptr);
  4.     nativeMessageQueue->wake();
  5. }
  6. void NativeMessageQueue::wake() {
  7.     mLooper->wake();
  8. }
  9. // eventfd 写数据,唤醒 epoll
  10. void Looper::wake() {
  11.     // 大体就是
  12.     write(mWakeEventFd.get(), &inc, sizeof(uint64_t));
  13. }
复制代码
  1. // 这个mWakeEventFd就是epoll关注的句柄之一
  2. void Looper::rebuildEpollLocked() {
  3.     struct epoll_event eventItem;
  4.     memset(& eventItem, 0, sizeof(epoll_event));
  5.     eventItem.data.fd = mWakeEventFd.get();
复制代码
  1. // 之前陷入阻塞,也是和eventItems有关
  2. int Looper::pollInner(int timeoutMillis) {
  3.     // ...
  4.     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 方法被唤醒。
  1. Looper::loop()
  2.     MessageQueue::next
  3.         MessageQueue::nativePollOnce
  4. ---jni---
  5. android_os_MessageQueue_nativePollOnce
  6.         NativeMessageQueue::pollOnce
  7.         Looper::pollOnce
  8.                 Looper::pollInner
  9.                         epoll_wait # 解除阻塞
复制代码
java

唤醒后,一样平常的流程就是从 mMessages 中找个符合的 message 返回,
MessageQueue::next()

  1. // frameworks/base/core/java/android/os/MessageQueue.java
  2. public final class MessageQueue {
  3. Message next() {
  4.         // ...
  5.     for (;;) {
  6.                 // 在这个位置陷入 Native 层,进入休眠状态
  7.         // 所以也是从这个位置唤醒
  8.         nativePollOnce(ptr, nextPollTimeoutMillis);
  9.         // 从 mMessages 链表中选取一个合适的 message 返回
  10.         synchronized (this) {
  11.             // Try to retrieve the next message.  Return if found.
  12.             final long now = SystemClock.uptimeMillis();
  13.             Message prevMsg = null;
  14.             Message msg = mMessages;
复制代码
Looper::loop

再继续返回后进入上一层
  1. // frameworks/base/core/java/android/os/Looper.java
  2. // frameworks/base/core/java/android/os/Looper.java
  3. public static void loop() {
  4.     // 进入无限循环,
  5.     for (;;) {
  6.         // 从这里恢复阻塞
  7.         Message msg = queue.next(); // MessageQueue.next() 获取 Message
  8.         // 分发消息,调用 handler 中的回调函数
  9.         msg.target.dispatchMessage(msg);
  10.     }
  11. }
复制代码
代码很多,焦点的流程只有两点:


  • next() 处返回一个符合的 message
  • 通过 msg.target.dispatchMessage(msg) 调用 handler 中的回调
至此,整个 Looper 流程就走完了。
唤醒后

  1. Looper.loop() # 唤醒后执行如下步骤
  2.         MessageQueue.next()                        # 获取msg
  3.         Handler.dispatchMessage         # 处理msg
  4.                 Handler.handleMessage
复制代码
获取MSG

Looper不停的调用,从消息队列中获取消息使用for循环
  1. // frameworks/base/core/java/android/os/Looper.java
  2. /**
  3. * Run the message queue in this thread. Be sure to call
  4. * {@link #quit()} to end the loop.
  5. */
  6. public static void loop() {
  7.     final Looper me = myLooper();
  8.     for (;;) {
  9.         // MessageQueue.next() 获取 Message,可能阻塞
  10.         Message msg = queue.next(); // might block
  11.         if (msg == null) {
  12.             // No message indicates that the message queue is quitting.
  13.             return;
  14.         }
  15.         // 处理MSG,下文会介绍
复制代码
处理MSG

主线程处理,之前传入MessageQueue的MSG,在主线程中实行。
  1. // frameworks/base/core/java/android/os/Looper.java
  2. public static void loop() {
  3.         // ...
  4.         // 由于阻塞,在 主线程唤醒后 开始处理获得的msg
  5.             // 分发消息,调用 handler 中的回调函数
  6.         msg.target.dispatchMessage(msg);
  7.     }
  8. }
复制代码
Message持有Handler,Handler持有Callback。
  1. // frameworks/base/core/java/android/os/Message.java
  2. public final class Message implements Parcelable {
  3.     @UnsupportedAppUsage
  4.     // 这个msg.target就是Handler的this指针,是其他线程初始化Msg时自动填入
  5.     /*package*/ Handler target;
复制代码
  1. // frameworks/base/core/java/android/os/Handler.java
  2. public class Handler {
  3.     public void handleMessage(@NonNull Message msg) {}
  4.     final Callback mCallback;
  5.     public interface Callback {
  6.         boolean handleMessage(@NonNull Message msg);
  7.     }
  8. }
复制代码
Handler::dispatchMessage

Handler的方法 handleMessage dispatchMessage 等,最终会调用到以下方法
  1. // frameworks/base/core/java/android/os/Handler.java
  2. /**
  3. * Handle system messages here.
  4. */
  5. public void dispatchMessage(@NonNull Message msg) {
  6.     if (msg.callback != null) {
  7.         handleCallback(msg);        // 1 Runnable run
  8.     } else {
  9.         if (mCallback != null) { // 2 final Callback mCallback;
  10.             if (mCallback.handleMessage(msg)) {
  11.                 return;
  12.             }
  13.         }
  14.         handleMessage(msg);
  15.     }
  16. }
  17. private static void handleCallback(Message message) {
  18.     message.callback.run(); // 1 Runnable callback;
  19. }
  20. public Handler(@Nullable Callback callback, boolean async) {
  21.     mLooper = Looper.myLooper();
  22.     mQueue = mLooper.mQueue;
  23.     mCallback = callback;                // 2 执行这里的 handleMessage
  24. }
  25. public void handleMessage(@NonNull Message msg) { // 3 执行子类的重载(通常说的就是这里)
  26. }
复制代码
Handler::handleMessage

这也是初始化Handler时,必要重写 handleMessage 的原因
在使用 Looper 的线程中通常会初始化一个 Handler 对象:
  1. // new 一个 Handler,覆写 handleMessage 方法
  2. mHandler = new Handler() {  
  3.     public void handleMessage(Message msg) {
  4.         //定义消息处理逻辑.
  5.     }
  6. };
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

半亩花草

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表