Handler消息机制的理解

先看一下消息机制的原理图:
这里写图片描述
源码相关调用:
这里写图片描述
相关源码说明

Message.java
    public int what;//标识(id)
    public int arg1;//保存int数据
    public int arg2;//保存int数据
    public Object obj;//保存任意数据
    long when;//记录应该被处理的时间值
    Handler target;//用来处理消息的Handler对象,就是发送消息的那个

Handler:发送消息,处理消息,移除消息
        1. 发消息
        public final boolean sendMessage (Message msg){
            return this.sendMessageDelayed(msg, 0L);//发送延时消息,延时为0
        }
        2. 发空消息,默认延时为0
        public final boolean sendEmptyMessage ( int what){
            return this.sendEmptyMessageDelayed(what, 0L);
        }
        3. 发空消息,延时为delayMillis
        public final boolean sendEmptyMessageDelayed ( int what, long delayMillis){
            Message msg = Message.obtain();
            msg.what = what;
            return this.sendMessageDelayed(msg, delayMillis);//发送延时消息,,延时为delayMillis
        }
        4. 发消息,延时delayMillis,计算出消息应该被处理时间when = 当前时间 + 延时
        public final boolean sendMessageDelayed (Message msg,long delayMillis){
            if (delayMillis < 0L) {
                delayMillis = 0L;
            }
            return this.sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
        }
        5.发消息,最终调用消息队列保存消息对象
        public boolean sendMessageAtTime (Message msg,long uptimeMillis){
            MessageQueue queue = this.mQueue;
        ......
            return this.enqueueMessage(queue, msg, uptimeMillis);
        }

        private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
            msg.target = this;//保存发送消息的Handler(Message.java 的target 赋值的地方)
            ......
            return queue.enqueueMessage(msg, uptimeMillis);//调用消息队列保存消息对象
        }


        6.移除消息
        public final void removeMessages(int what) {
            this.mQueue.removeMessages(this, what, (Object)null);//调用消息队列移除它内部的指定what消息
        }
        7.处理消息的回调方法
        public void handleMessage(Message msg) {
        }
        8.
        public void dispatchMessage(Message msg) {
            if(msg.callback != null) {//消息自己可以处理,让消息自己处理
                handleCallback(msg);
            } else {
                //如果Handler对象中有回调监听,调用回调器来处理消息
                if(this.mCallback != null && this.mCallback.handleMessage(msg)) {
                    return;
                }

                this.handleMessage(msg);//让Handler的handleMessage来处理。
            }

        }

MessageQueue:存储消息,以Message的when排序
        1.将Message添加到队列中
        boolean enqueueMessage(Message msg, long when) {
            .....
            msg.when = when;//执行消息应该被处理的时间(Handler中发消息,延时delayMillis,计算出的时间when = 当前时间 + 延时)
            if (p != null && when != 0L && when >= p.when) {//将当前消息保存到消息队列中的一个合适的位置
                needWake = this.mBlocked && p.target == null && msg.isAsynchronous();
                while (true) {
                    Message prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        msg.next = p;
                        prev.next = msg;
                        break;
                    }

                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
            } else {//消息队列为空的或者没有消息的when比新插入消息的when小,则该消息插入到第一个位置
                msg.next = p;
                this.mMessages = msg;
                needWake = this.mBlocked;
            } //最终得到的结果是:消息队列是按when来排序的。
            nativeWake(this.mPtr);//通过本地方法实现对处理等待状态的底层线程
        }
        2.取出一个合适的Message对象,可能不会立即返回
        Message next() {
            .....
            this.nativePollOnce(ptr, nextPollTimeoutMillis);//本地方法,会导致可能处理等待状态,但不会阻塞主线程
            .....
            Message msg = this.mMessages;//取出消息队列中的第一个消息
            .....
            return msg;//返回
        }

Looper.java
        1. 核心方法
        public static void loop() {
            Looper me = myLooper();//得到Looper对象
            while(true) {//无限循环
                Message msg = queue.next();//从消息队列中取出消息
                msg.target.dispatchMessage(msg); // 调用Handler去分发并处理消息
                msg.recycleUnchecked();//回收利用Message
            }

        }

猜你喜欢

转载自blog.csdn.net/qq_41642206/article/details/80536998