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

 

posted on 2020-04-23 16:47  青年程序猿  阅读(845)  评论(0编辑  收藏  举报