Handler---4部曲 --- 1. 总体流程

作者: liys_android | 来源:发表于2021-11-06 23:38 被阅读0次

    Handler---4部曲---1. 总体流程
    Handler---4部曲---2. ThreadLocal 存储主流程
    Handler---4部曲---3. MessageQueue队列
    Handler---4部曲---4.细节补充

    为什么分4篇呢?
    因为我在看别人的博客中发现,人集中注意力的时间是有限的, 看太长时间容易累, 无法集中注意力,Handler的内容还是有点东西的.

    Handler整体流程图.png
    一 . ActivityThread中的main方法
    public static void main(String[] args) {
            Looper.prepareMainLooper();
            Looper.loop();
    }
    

    总结: App启动, 执行2个方法.

    1. Looper.prepareMainLooper()分析

    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    
        //Looper.java
        @Deprecated
        public static void prepareMainLooper() {
            prepare(false);
            synchronized (Looper.class) {
                if (sMainLooper != null) { //重复创建抛异常
                    throw new IllegalStateException("The main Looper has already been prepared.");
                }
                sMainLooper = myLooper();
            }
        }
    
        private static void prepare(boolean quitAllowed) {
            if (sThreadLocal.get() != null) { //重复创建抛异常
                throw new RuntimeException("Only one Looper may be created per thread");
            }
            //创建Looper对象, 保存到sThreadLocal中
            sThreadLocal.set(new Looper(quitAllowed));
        }
    
        private Looper(boolean quitAllowed) {
            mQueue = new MessageQueue(quitAllowed);
        }
    

    总结:
    1. 创建Looper对象(每个线程只有一个), 保存到sThreadLocal中
    2. 创建队列mQueue = new MessageQueue(...) , mQueue是Looper对象的成员变量

    Looper.loop() 分析

       public static @Nullable Looper myLooper() {
            return sThreadLocal.get();
        }
    
    public static void loop() {
             // 1.从sThreadLocal中, 获取的Looper对象
            Looper me = myLooper(); 
            // 2.从Looper中, 获取队列
            MessageQueue queue = me.mQueue;
            for (;;) {
                //循环取出消息
                Message msg = queue.next();
                //处理消息
                msg.target.dispatchMessage(msg);
                //释放资源
                msg.recycleUnchecked(); 
           }
    }
    

    总结:sThreadLocal--->取出当前线程Looper对象--->取出队列, 循环从队列取出消息处理

    二. Handler发送消息

    new Handler()
        public Handler(xxx) {
              mLooper = Looper.myLooper();
              mQueue = mLooper.mQueue;
        }
    

    总结:从Looper中取出队列, Handler中的mQueue 就是 Looper中的队列

    handler.post(xxx), handler.sendXxx(...)
        public boolean sendMessageAtTime(@NonNull Message msg, long uptimeMillis) {
            MessageQueue queue = mQueue;
            enqueueMessage(queue, msg, uptimeMillis);
        }
    
        private boolean enqueueMessage(MessageQueue queue, Message msg,
                long uptimeMillis) {
            msg.target = this; //带着当前的Handler.
            return queue.enqueueMessage(msg, uptimeMillis);
    }
    

    总结: msg携带当前的Handler对象, 加到队列中.

    总体流程完结

    细节1:Main函数,不允许再次初始化.

    Looer.prepareMainLooper.png

    细节2:每个线程只允许prepare()初始化一次

    Looper.prepare().png

    相关文章

      网友评论

        本文标题:Handler---4部曲 --- 1. 总体流程

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