Android handler机制

来源:互联网 发布:网络直播app电视版 编辑:程序博客网 时间:2024/06/06 12:26

Handler机制是线程间通信的实现;

Handler类持有MessageQueue 引用,Looper引用。主要是用来处理Message的发送,入列和出列;

持有Looper引用的目的是获取MessageQueue引用,Looper通过ThreadLocal才属于它的线程(主线程或子线程),由于主线程之前就持有自己的Looper对象,所以实例化Handler的时候不用调用Looper.prepare()方法进行Looper的设定,直接在主线程中实例化Handler对象就可以发送消息;

Looper类持有一个MessageQueue引用,用来对queue中的Message进行循环处理;

如果Handler是在子线程中实例化的,那么它持有的Looper就是属于该子线程的,在子线程中进行消息的循环需要先设定Looper:

public void run(){Looper.prepare();//会实例化一个looper对象,并属于当前线程handler = new Handler(){public void handleMessage(Message msg){}}Looper.loop();//获取当前线程的looper进行循环}

Handler在哪个线程中实例化,那么它就处理该线程中的消息;可是如果多个线程同时通过这个handler发送消息呢,由于Looper是线程隔离的,但是messageQueue却要暴露给其他的线程,这样才能允许其他的线程发送入列消息,所以MessagQueue入列时需要同步化:

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(TAG, e.getMessage(), e);                msg.recycle();                return false;            }<span style="white-space:pre"></span>    msg.markInUse();            msg.when = when;            Message p = mMessages;            boolean needWake;
<span style="white-space:pre"></span>   //如果链表没有节点,或时间为0,或小于头节点,则            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;
<span style="white-space:pre"></span>    //如果到了链表的最后或时间小于某一节点,则插入到该节点之前                    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;    }


Message类持有一个链表,它会缓存用过的Messages,loop循环就是不断的从链表头中取出消息,如果取出的是null则中断loop:

Message next() {        // Return here if the message loop has already quit and been disposed.        // This can happen if the application tries to restart a looper after quit        // which is not supported.        final long ptr = mPtr;        if (ptr == 0) {            return null;        }        int pendingIdleHandlerCount = -1; // -1 only during first iteration        int nextPollTimeoutMillis = 0;        for (;;) {            if (nextPollTimeoutMillis != 0) {                Binder.flushPendingCommands();            }            nativePollOnce(ptr, nextPollTimeoutMillis);            synchronized (this) {                // Try to retrieve the next message.  Return if found.                final long now = SystemClock.uptimeMillis();                Message prevMsg = null;                Message msg = mMessages;                if (msg != null && msg.target == null) {                    // Stalled by a barrier.  Find the next asynchronous message in the queue.                    do {                        prevMsg = msg;                        msg = msg.next;                    } while (msg != null && !msg.isAsynchronous());                }                if (msg != null) {                    if (now < msg.when) {                        // Next message is not ready.  Set a timeout to wake up when it is ready.                        nextPollTimeoutMillis = (int) Math.min(msg.when - now, Integer.MAX_VALUE);                    } else {                        // Got a message.                        mBlocked = false;                        if (prevMsg != null) {                            prevMsg.next = msg.next;                        } else {                            mMessages = msg.next;                        }                        msg.next = null;                        if (DEBUG) Log.v(TAG, "Returning message: " + msg);                        msg.markInUse();                        return msg;                    }                } else {                    // No more messages.                    nextPollTimeoutMillis = -1;                }
<span style="white-space:pre"></span>// Process the quit message now that all pending messages have been handled.                if (mQuitting) {                    dispose();                    return null;                }




0 0
原创粉丝点击