美文网首页
Android Handler基本原理

Android Handler基本原理

作者: Athephoenix | 来源:发表于2020-05-04 22:13 被阅读0次

Android 中Handler 常用来做线程间通讯,另一种说法是用来切换线程,笔者认为称之通讯更为妥当,为什么这么说呢,这得从基本原理说起。

首先Handler的主要相关的对象:

ThreadLocal, Looper, MessageQueue

ThreadLocal的功能及属性可以自行了解。

MessageQueue 主要包含的两个操作,插入和读取。
其内部数据结构是一个单链表,在插入上有优势,插入和读取分别对应enqueueMessage和next 方法,

next方法源码如下:

 int pendingIdleHandlerCount = -1; // -1 only during first iteration
 int nextPollTimeoutMillis = 0;
 for (;;) {
     if (nextPollTimeoutMillis != 0) {
         Binder.flushPendingCommands();
     }

     nativePollOnce(ptr, nextPollTimeoutMillis);

     synchronized (this) {
         // Try to retrieve the next message.  Return if found.
         final long now = SystemClock.uptimeMillis();
         Message prevMsg = null;
         Message msg = mMessages;
         if (msg != null && msg.target == null) {
             // Stalled by a barrier.  Find the next asynchronous message in the queue.
             do {
                 prevMsg = msg;
                 msg = msg.next;
             } while (msg != null && !msg.isAsynchronous());
         }
      ...
 }

这里有两点:

  1. next方法为无限for循环方法
  2. for内部的nativePollOnce(ptr, nextPollTimeoutMillis); 为阻塞方法,

也就是会一直阻塞等待新的消息到来,
Looper.loop() 内部也是一个for循环方法

 public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;

        // Make sure the identity of this thread is that of the local process,
        // and keep track of what that identity token actually is.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();

        // Allow overriding a threshold with a system prop. e.g.
        // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start'
        final int thresholdOverride =
                SystemProperties.getInt("log.looper."
                        + Process.myUid() + "."
                        + Thread.currentThread().getName()
                        + ".slow", 0);

        boolean slowDeliveryDetected = false;

        for (;;) {
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }
          ...
           msg.target.dispatchMessage(msg);
          ...
        }  

可以注意到loop的for循环的结束条件是msg == null,也就是queue.next()返回 null 时,
这也就是looper.quit()调用时;

loop()通过msg.target.dispatchMessage(msg); msg.target 就是handle对象,通过其内部的dispatchMessage();完成消息分发,messageQueue的阻塞流程唤醒,进行后续业务。

到这里,也就是完成了A线程的消息,通过B线程创建的Handler传递消息,并在B线程进行业务;所以笔者理解为主动通讯,被动切换线程;

相关文章

网友评论

      本文标题:Android Handler基本原理

      本文链接:https://www.haomeiwen.com/subject/tvrughtx.html