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的線程。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM