Handler 是如何跨线程的

Before

Lopper是跨进程的关键类,阅读本文之前最好先熟悉Looper,MessageQueue为好;

先看源码
public class Handler {
    final MessageQueue mQueue;

    public final boolean sendMessage(Message msg) {
        return sendMessageDelayed(msg, 0);
    }
    public final boolean sendMessageDelayed(Message msg, long delayMillis){
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }
    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }
    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);//回调到熟悉的方法啦
        }
    }
}
分析
  • 由熟悉的sendMessage开始,最后都是调用enqueueMessage方法,而最终还是调用MessageQueue类的enqueueMessage方法(点我),到此为止我们一般都是在新线程调用;
  • 接下来Looper类的loop方法会在当前线程(如果是更新UI则在主线程)从MessageQueue中获取最新消息,通过msg.target.dispatchMessage(msg);调用到Handler中来(上述代码),然后调用到handlemessage(msg)我们就熟悉啦;
  • 由此,Handler跨线程最重要的是在当前线程(初始化Handler的线程)进行loop轮询,而变量是可以在不同线程访问·的,所以Handler可以在其他线程向MessageQueue中插入数据,而loop则在当前线程不断去取数据,取得数据就回调,达到跨线程的目的;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容