Android handler源码一瞥

194 阅读4分钟

Handler的各个构造函数最终会执行到两个不同的构造函数中

public Handler(@Nullable Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class<? extends Handler> klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&(klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +klass.getCanonicalName());
            }
        }
	//从Looper里拿到
        mLooper = Looper.myLooper();
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");
        }
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

 @UnsupportedAppUsage
    public Handler(@NonNull Looper looper, @Nullable Callback callback, boolean async) {
        mLooper = looper;
        mQueue = looper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }

这两种构造函数的区别在于有没有传入一个Looper对象,如果没有传入Looper对象即从Looper的mtQueue()方法获得当前线程的thread local中的looper.

/**
     * Return the Looper object associated with the current thread.  Returns
     * null if the calling thread is not associated with a Looper.
     */
    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }

如果当前线程没有looper,并且没有传入looper就会抛出异常.

发送消息除了sendEmptyMessageAtTime(int what, long uptimeMillis)以外都会调用sendMessageDelayed

//从构造方法中传入或是从treadlocal中获得的
final MessageQueue mQueue;
public final boolean sendEmptyMessageAtTime(int what, long uptimeMillis) {
        Message msg = Message.obtain();
        msg.what = what;
        return sendMessageAtTime(msg, uptimeMillis);
    }

public final boolean sendMessageDelayed(@NonNull Message msg, long delayMillis) {
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }

public boolean sendMessageAtTime(@NonNull 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);
    }

private boolean enqueueMessage(@NonNull MessageQueue queue, @NonNull Message msg,
        long uptimeMillis) {
        //⚠️注意这里将message的target设为了当前的handler
        msg.target = this;
        msg.workSourceUid = ThreadLocalWorkSource.getUid();

        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

可以看到handler中的sendmessage最终会调用到当前线程中或传入的messagequeue中的enqueueMessage

boolean enqueueMessage(Message msg, long when) {

  msg.markInUse();
  //给message赋值执行时间
  msg.when = when;
  
  Message p = mMessages;//下一个应该处理的message
  boolean needWake;
  //判断当前消息队列中没有需要处理的message或要插入的message没有延迟或执行时间在当前最靠前的message之前
  if (p == null || when == 0 || when < p.when) {
    // New head, wake up the event queue if blocked.
    msg.next = p;
    mMessages = msg;
    //mBlocked为标记当前消息队列是否阻塞的变量量
    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;
    
    //按被插入的message触发时间进行插入
    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;
}

   

接下来看一下looper里的循环

public static void loop() {

	···


  	//这里就是looper里的死循环
    for (;;) {
      Message msg = queue.next(); // might block
      
      //只有queue里没有消息了才会退出循环
      if (msg == null) {
        // No message indicates that the message queue is quitting.
        return;
      }

   ···
     //处理消息
     msg.target.dispatchMessage(msg);
   ···

      msg.recycleUnchecked();
    }
  }

可以看到在循环中会取出queue中的message,直到queue里没有消息.在处理完当前消息后再将它回收掉.

这里处理消息时使用了在handler中enqueueMessage时设置的target,将消息发送回将消息加入队列的handler进行处理.这里的msg.recycleUnchecked()是默认权限的方法,所以只有在与message包相同的类才能访问到

public void dispatchMessage(@NonNull Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
          //mCallback是创建handler时的传入的参数
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

handler进行消息处理时会优先交给callback的处理,其次是交给handler创建时传入的callbak处理,再调用handler类中的handleMessage,但如果没有继承handler重写,handleMessage会是一个空方法.

接下来再看一下从queue中获取message的方法

@UnsupportedAppUsage
Message next() {
  ···
  for (;;) {
    
    if (nextPollTimeoutMillis != 0) {
      //这是一个native方法
      Binder.flushPendingCommands();
    }
	//处理nextPollTimeoutMillis的逻辑在native层
    nativePollOnce(ptr, nextPollTimeoutMillis);

    synchronized (this) {
      // 尝试返回下一个message
      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());
      }
      if (msg != null) {
        if (now < msg.when) {
          // 下一个message还没有到设定的时间.  设置一个超时时间
          nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);
        } else {
          // Got a message.
          mBlocked = false;
          if (prevMsg != null) {
            prevMsg.next = msg.next;
          } else {
            mMessages = msg.next;
          }
          msg.next = null;
          if (DEBUG) Log.v(TAG, "Returning message: " + msg);
          msg.markInUse();
          return msg;
        }
      } else {
        // No more messages.
        nextPollTimeoutMillis = -1;
      }

      // 当被标记退出循环时执行
      if (mQuitting) {
        dispose();
        return null;
      }

      // If first time idle, then get the number of idlers to run.
      // Idle handles only run if the queue is empty or if the first message
      // in the queue (possibly a barrier) is due to be handled in the future.
      if (pendingIdleHandlerCount < 0
          && (mMessages == null || now < mMessages.when)) {
        pendingIdleHandlerCount = mIdleHandlers.size();
      }
      if (pendingIdleHandlerCount <= 0) {
        // 没有需要处理的消息,标记消息队列阻塞
        mBlocked = true;
        continue;
      }

      if (mPendingIdleHandlers == null) {
        mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
      }
      mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
    }
    
	// 只有当消息队列空闲的时候才会执行到这里
    // 执行idle handlers.
    
    ···
    //当执行了idle handlers后会将nextPollTimeoutMillis重置为0
    nextPollTimeoutMillis = 0;
  }
}