Handler源码认知

来源:互联网 发布:python工具 量化交易 编辑:程序博客网 时间:2024/05/18 01:31

Handler是面试一定会问得机制,每次都能够打上来,但是答的很浅,只是说了大概的一个工作机制,画了个图从源码的角度加深自己的理解吧。首先上图





上面是大概的一个工作机制,从源码的角度来说其实没有太多重要的地方,主要就关注这么几个类

Message:承载着消息的对象。

MessageQueue:存放消息的队列

Handler:负责发送消息和接收消息的对象

Looper:消息循环机制

通常都会使用消息池机制,如下可以获得一个Message对象

Message.obtain(this)obtain()message.sendToTarget();Message message = handler.obtainMessage();//从源码的角度来说其实在里面做了那么一件事情,它会把当前的那个handler传进来,到之后后面的message可以直接调用//message.sendToTarget();public static Message obtain(Handler h) {        Message m = obtain();        m.target = h;        return m;    }在obtain这个方法里面又干了这么一件事情  public static Message obtain() {        synchronized (sPoolSync) {            if (sPool != null) {                Message m = sPool;                sPool = m.next;                m.next = null;                m.flags = 0; // clear in-use flag                sPoolSize--;                return m;            }        }        return new Message();    }//看看就能够知道了,第一次创建的时候是没有消息池的,直接new 了一个对象出去,在后面会把该消息放入消息池//这里完成了消息的初始化,当执行完自己的逻辑之后调用message.sendToTarget();通过保存在message内部的//handler发送消息到消息池里面   boolean enqueueMessage(Message msg, long when) {        if (msg.target == null) {            throw new IllegalArgumentException("Message must have a target.");        }        if (msg.isInUse()) {            throw new IllegalStateException(msg + " This message is already in use.");        }        synchronized (this) {            if (mQuitting) {                IllegalStateException e = new IllegalStateException(                        msg.target + " sending message to a Handler on a dead thread");                Log.w("MessageQueue", e.getMessage(), e);//在这里实现了消息的回收,实际上就是把消息放回消息池                msg.recycle();                return false;            }            msg.markInUse();            msg.when = when;            Message p = mMessages;            boolean needWake;            if (p == null || when == 0 || when < p.when) {                // New head, wake up the event queue if blocked.                msg.next = p;                mMessages = msg;                needWake = mBlocked;            } else {                // Inserted within the middle of the queue.  Usually we don't have to wake                // up the event queue unless there is a barrier at the head of the queue                // and the message is the earliest asynchronous message in the queue.                needWake = mBlocked && p.target == null && msg.isAsynchronous();                Message prev;                for (;;) {                    prev = p;                    p = p.next;                    if (p == null || when < p.when) {                        break;                    }                    if (needWake && p.isAsynchronous()) {                        needWake = false;                    }                }                msg.next = p; // invariant: p == prev.next                prev.next = msg;            }            // We can assume mPtr != 0 because mQuitting is false.            if (needWake) {                nativeWake(mPtr);            }        }        return true;    }

以上就是对handler的理解


0 0