个人对handler的理解

handler有时会使用
post和postDelayed方法去执行一些任务,这里就从这两个方法去看一下hanlder在执行这两个方法的时候都做了什么个人对handler的理解个人对handler的理解

handler的post方法最终调用的是sendMessageDelayed,而handler的postDelayed方法(不管是三个参数还是两个参数的都会)最终也会调用到sendMessageDelayed方法当中。

sendMessageDelayed的方法里面会首先判断当前是否有消息队列(MessageQueue),如果为null则抛出异常。没有的话就去执行enqueueMessage方法。

个人对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(TAG, 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;
    }

enqueueMessage方法在MessageQueue当中,方法进来之后会首先判断message的target和isinuse。
如果target不为null,isInUser不为true的话就会进入到同步锁的代码块当中(这里之所以加锁以我目前的拙见是因为这个方法会被handler多次调用有多线程的情况,暂时没有找到代码块可以佐证这个想法),进来之后会首先判断mQuitting的状态,该变量只有在退出消息队列的时候才会置为true(布尔值在声明的时候如果没有设置过值,默认值为false)。
不为true之后,就会走到后面的判断。大家可以看到第一个判断,有三个判断条件。分别判断的是message是空的,时间是否为0,时间是否小于message的时间。
如果符合这个判断条件的话,就会把传递过来的message赋值给当前的message然后传递出去。
如果不符合第一个判断的条件就会进入到else里面。
个人对handler的理解

咱们先看一下代码里面的这块注释的大概意思,
个人对handler的理解
可以看到这里说明了这部分会把消息插入到队列当中,直到消息在消息队列的头部。
这里有一个for循环,会循环获取消息,判断消息的状态。直到消息为null或者时间小于消息的设定时间,才会退出此循环(之前印象当中跟我说handler里面有一个无限for循环,看来其实是在消息队列里面)。从这个流程就可以看出消息通过post和postDelayed这两个方法的执行过程是怎么走的了。

上一篇:Be careful when emitting branches in C1 LIR


下一篇:两个变量组合判空,idea智能提示Condition ‘b == null‘ is always ‘true‘ when reached