• Handler实现机制,同步屏障,IdleHandler


    handler 通过sentMessage 发送到 MessageQueue中,通过Looper的处理(可以通过Looper.myQueue()得到当前线程的消息队列)

    一个for 循环 ,循环从MessageQueue中拿消息进行处理

        public static void loop() {
            final Looper me = myLooper();   //获得当前的Looper
            if (me == null) {
                throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
            }
            
            final MessageQueue queue = me.mQueue;  //获取当前Looper的消息队列
            //......
    
            for (;;) {
                Message msg = queue.next();  //取出队头的消息
                if (msg == null) {
                    // 如果消息为空,则跳过,继续执行下一个message
                    return;
                }
                //......
                try {
                    msg.target.dispatchMessage(msg);
                    //......
                } finally {
                   //......
                }
               //......
                msg.recycleUnchecked();  //回收可能正在使用的消息
            }
        }

    然后通过dispatchMessage 分发到相对应的target (即发送消息的那个Handler)

    handler 进行handlerMessage的回掉

    APP应用启动的时候在主线程会创建一个MainLooper

    所以在主线程创建的handler 是可以更新UI的 因为默认的looper在主线程,

    而子线程是直接创建handler会报错,必须在创建handler之前给该子线程创建一个looper (Lopper.prepare)

    new Thread(new Runnable() {  
                public void run() {  
                    Handler handler new Handler(){  
                        @Override  
                        public void handleMessage(Message msg) {  
                            Toast.makeText(getApplicationContext(), "handler msg", Toast.LENGTH_LONG).show();  
                        }  
                    };  
                    handler.sendEmptyMessage(1);  
                      
                };  
            }).start();  

    上面找个会报错

    new Thread(new Runnable() {  
                public void run() {  
                    Looper.prepare();  // 此处获取到当前线程的Looper,并且prepare()  
                    Handler handler = new Handler(){  
                        @Override  
                        public void handleMessage(Message msg) {  
                            Toast.makeText(getApplicationContext(), "handler msg", Toast.LENGTH_LONG).show();  
                        }  
                    };  
                    handler.sendEmptyMessage(1);  
                     Looper.loop();//不断遍历 消息队列中的消息
                };  
            }).start();  

    一个线程有且只能绑定一个Looper,只有一个messageQueue ,可以创建无数个handler

    handlerMessage 所在的线程是该looper所在的线程,即创建该Looper的线程。

  • 相关阅读:
    洛谷P5173 传球(暴力)
    uoj#402. 【CTSC2018】混合果汁(主席树+二分)
    uoj#401. 【CTSC2018】青蕈领主(分治FFT)
    uoj#400. 【CTSC2018】暴力写挂(边分治)
    uoj#399. 【CTSC2018】假面(概率期望)
    P4769 [NOI2018]冒泡排序(dp)
    洛谷P3688/uoj#291. [ZJOI2017]树状数组
    uoj#290. 【ZJOI2017】仙人掌(数数+仙人掌+树形dp)
    Git环境部署
    mysql修改密码
  • 原文地址:https://www.cnblogs.com/androidxufeng/p/12753453.html
Copyright © 2020-2023  润新知