Handler post(Runnable runnable)中的runnable是在子线程,还是在主线中执行?

97 阅读2分钟

首先看下psot的方法

最终还是调用到了sendMessageDelayed的方法,蒋runnable存到了一个message中了

public final boolean post(@NonNull Runnable r) {
   return  sendMessageDelayed(getPostMessage(r), 0);
}

sendMessageDelayed方法

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

sendMessageAtTime方法

将msg加入了MessageQueue中

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) {
    msg.target = this;
    msg.workSourceUid = ThreadLocalWorkSource.getUid();

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

MessageQueue中将msg加入到队列的逻辑

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;

既然加入到队列中了,那么肯定有逻辑去取出队列中的msg,然后做相应的处理逻辑 还记得我们在创建Handler对应的时候,有传入Looper.getMainLooper(),或者传入HandlerThread.getLooper()吗?

创建Handler对象

HandlerThread mHandlerThread = new HandlerThread("workThread");
mHandlerThread.start();
Handler mHander = new Handler(mHandlerThread.getLooper()); // 对应的Thread是HandlerThread
或者是:
Handler mHander = new Handler(Looper.getMainLooper()); // 对应的Thread是ActivityThread

HandlerThread start()后执行到run()

public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
    Looper.loop();
    mTid = -1;
}

Looper.loop()一直在循环loop message

从这里也可以看到Looper.loop()运行在HandlerThread类的run()方法里面,那么Looper.loop()中的所有任务都是执行在HandlerThread的这个子线程中

for (;;) {
    if (!loopOnce(me, ident, thresholdOverride)) {
        return;
    }
}
  1. me.mQueue.next()获取到队列中的msg
  2. msg.target.dispatchMessage(mgs)来分发处理msg
private static boolean loopOnce(final Looper me,
        final long ident, final int thresholdOverride) {
    Message msg = me.mQueue.next(); // might block
    
    ...
    
    try {
        msg.target.dispatchMessage(msg);
        if (observer != null) {
            observer.messageDispatched(token, msg);
        }
        dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
    } catch (Exception exception) {
        if (observer != null) {
            observer.dispatchingThrewException(token, msg, exception);
        }
        throw exception;
    } finally {
        ThreadLocalWorkSource.restore(origWorkSource);
        if (traceTag != 0) {
            Trace.traceEnd(traceTag);
        }
    }
    
    ...

}

Handler.java中dispatchMessage()

public void dispatchMessage(@NonNull Message msg) {
    if (msg.callback != null) {
        handleCallback(msg);
    } else {
        if (mCallback != null) {
            if (mCallback.handleMessage(msg)) {
                return;
            }
        }
        handleMessage(msg);
    }
}
  1. 如果前面Handler的构造方法里面传入的是HandlerThread的Looper,那么这里message.callback.run()就是执行在HandlerThread的子线程中
  2. 如果前面Handler的构造方法里面传入的是主线程的Looper,也就是Looper.getMainLooper(),那么这里message.callback.run()就是执行在主线程中。
private static void handleCallback(Message message) {
    message.callback.run();
}