美文网首页
Handler、Looper与MessageQueue之间的关系

Handler、Looper与MessageQueue之间的关系

作者: 锦岳 | 来源:发表于2020-07-28 17:16 被阅读0次
    • Handler 封装了消息的发送,也负责接收消息,内部会与Looper 关联
    • Looper封装了线程中的消息循环,内部包含了MessageQueue,负责从MessageQueue取出消息,然后交给Handler 处理
    • MessageQueue就是一个消息队列,负责存储消息,收到消息就存储起来,Looper会循环从MessageQueue读取消息

    1. Handler
    public Handler(Callback callback, boolean async) {
        // ...
        mLooper = Looper.myLooper();
        // ...
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
    
    1. Looper.myLooper()
    public static @Nullable Looper myLooper() {
        return sThreadLocal.get();
    }
    

    sThreadLocal 是一个 ThreadLocal 对象,可以在一个线程中存储变量。底层是 ThreadLocalMap(一个Map类型)

    1. ActivityThread.main()

    ActivityThread 是 Android App进程的初始类,main函数是App进程的入口。

    public static final void main(String[] args) {
        Looper.prepareMainLooper();
        if(sMainThreadHandler == null) {
            sMainThreadHandler = new Handler();
        }
    
        ActivityThread thread = new ActivityThread();
        thread.attach(false);
    
        if(false) {
            Looper.myLooper().sendMessageLogging(new LogPrinter(Log.DEBUG, "ActivityThread"));
        }
    
        Looper.loop();
    }
    
    1. Looper.prepareMainLooper()
    public static void prepareMainLooper() {
        prepare(false);
        synchronized (Looper.class) {
            if(sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }
    

    该方法会新建一个 Looper 对象并存储在 sThreadLocal 中。

    1. Looper.prepare()
    private static void prepare(boolean quitAllowed) {
        if(sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }
    
    1. Looper 构造器
    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }
    
    1. Looper.loop()
    
    

    该方法是一个死循环,会一直从 MessageQueue 中获取消息。如果获取到消息,就会执行 msg.target.dispatchMessage(msg),其中 msg.target 就是 Handler 对象,也就是调用 Handler 的 dispatchMessage() 方法,然后将从 MessageQueue 中获取的消息传入。

    1. Handler.dispatchMessage() 方法

    dispatchMessage() 方法对消息进行最后的处理,如果是 post 类型,就调用 handlerCallback 方法处理,否则是 sendMessage 发送的消息。先查看是否有拦截,如果没有,最终就调用 handlerMessage 方法进行处理。

    
    public void dispatchMessage(Message msg) {
        // 如果 callback 不为空,说明发送消息时是发送一个 Runnable 对象
        if(msg.callback != null) {
            handleCallback(msg);
        } else {
            if(mCallback != null) { // 这是用来拦截消息的
                if(mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg); // 最终调用重写的 handleMessage() 方法
        }
    }
    
    
    1. Handler.handleCallback()
    private static void handleCallback(Message msg) {
        msg.callback.run();
    }
    

    相关文章

      网友评论

          本文标题:Handler、Looper与MessageQueue之间的关系

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