Android-Handler源码

一、什么是Handler

1.Android SDK中用来处理异步消息的核心类
2.子线程可以通过Handler来通知主线程进行UI更新

二、Handler机制的核心类

Handler:mLooper,mQueue(mLooper是从Looper中的ThreadLocal对象中获取的,整个app中,所有的Looper对象都是保存在Looper类中的ThreadLocal静态对象中,mQueue是根据mLooper中的mQueue赋值的)
Message
Looper:mQueue(是一个MessageQueue对象)
MessageQueue:采用单链表的方式存储Handler需要处理的Message信息

Message:
在整个消息机制中,Message又叫Task,封装了任务携带的信息和处理该任务的Handler:
1.尽管Message有public默认的构造方法,但是应该通过Message.obtain()来从消息池中获取空消息对象,以节省资源。
2.Message如果只需要携带简单的int信息,请优先使用arg1和arg2来传递消息,这比使用Bundle更节省内存。

Looper:轮循器
在Looper内部有一个Thread对象,存放Looper对应的当前线程对象。Looper内部有一个MessageQueue队列。用来存放消息。Looper轮循的时候,都是从当前线程的Looper对象中取出MessageQueue,而当前线程的Looper对象从ThreadLocal中获得。而ThreadLocal对象则是在Looper中的一个静态对象,是一个全局的。

三、原理分析

1.Looper实例创建和保存原理分析

MessageQueue 就是设计模式中的缓冲区,它负责接收生产者发送过来的数据先进先出的队列形式,保存着所有消息。在UI Thread中通过looper 不断从MessageQueue 取出消息在执行任务。

Handler中获取Looper对象:
public Handler(Callback callback, boolean async) {
   //省略一些无关代码
    mLooper = Looper.myLooper();
    if (mLooper == null) {
        throw new RuntimeException(
            "Can't create handler inside thread that has not called Looper.prepare()");
    }
    mQueue = mLooper.mQueue;
    mCallback = callback;
    mAsynchronous = async;
}
public static @Nullable Looper myLooper() {
    return sThreadLocal.get();
}

在Android中,所有的Looper对象都是保存在一个全局的ThreadLocal对象中,Handler在线程中获取Looper对象的时候,是调用ThreadLocal的get方法,ThreadLocal的get方法中,会优先获取当前线程对象。

ThreadLocal的get方法的实现:
public T get() {
    Thread t = Thread.currentThread();
    ThreadLocalMap map = getMap(t);
    if (map != null) {
        ThreadLocalMap.Entry e = map.getEntry(this);//this是ThreadLocal对象
        if (e != null) {
            @SuppressWarnings("unchecked")
            T result = (T)e.value;//value即为Looper对象
            return result;
        }
    }
    return setInitialValue();
}
    //ThreadLocal的getMap的源码:
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

其实每个Thread线程中都会有一个ThreadLocalMap对象。每个线程对应的Looper实例,其实就是保存在每个线程实例中的ThreadLocalMap实例中

Looper 的主要工作就是维护MessageQueque中的消息队列,它负责从MessageQueue中取出要执行的消息任务,先判断Looper是否为null,不为null就循环状态不断从MessageQueue中取出消息,然后通过dispatchMessage派发出去就行处理。

看下Looper的创建过程:
public static void loop() {
    // 调用Looper.myLooper()方法,从ThreadLocal中取出当前线程的Looper对象
    final Looper me = myLooper();
    // 如果当前线程中的Looper对象为null,则会抛出异常
    if (me == null) {
        throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
    }
    final MessageQueue queue = me.mQueue;
    .....
    for (;;) {
        // 通过一个死循环,从MessageQueue中不停的取出消息
        Message msg = queue.next(); // might block
            if (msg == null) {
                // 由于刚创建的MessageQueue就开始轮询,队列里没有消息
                // 等到Handler调用send或者post发送消息,进而调用MessageQueue.enqueueMessage后
                // 队列里才有消息
                return;
            }
            ........
            try {
               // 分发信息,target是一个Handler对象,这里就是调用Handler来分发信息的。
                msg.target.dispatchMessage(msg);
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
            .........
            msg.recycleUnchecked();
        }
    }

每个线程只能有一个Looper对象,而且是通过ThreadLocal来存放,其他线程无法访问当前的Looper。

static final ThreadLocal sThreadLocal = new ThreadLocal();

Looper可以让一个普通线程具有消息循环的能力,这是源码给出的一段示例。

class LooperThread extends Thread {
     public Handler mHandler;

     public void run() {
         Looper.prepare();

         mHandler = new Handler() {
            public void handleMessage(Message msg) {
                // process incoming messages here
            }
        };

        Looper.loop();
     }

每个application都默认拥有一个Looper对象注释可以看到。在启动应用程序进程过程中,会在最后调用ActivityThread.main方法,在ActivityThread.main方法中会调用Looper.prepareMainLooper()方法初始化主线程的Looper实例,所以说UI线程默认就有一个Looper对象,可通过Looper.myLooper()方法获取到。因为Looper中用来保存Looper实例的ThreadLocal是一个静态常量,内存中只有这一个。又根据ThreadLocal的set和get的特性,所以可以根据不同的线程取出不同的值

    /**
     * Initialize the current thread as a looper, marking it as an
     * application's main looper. The main looper for your application
     * is created by the Android environment, so you should never need
     * to call this function yourself.  See also: {@link #prepare()}
     */
    public static void prepareMainLooper() {
        // 这里传入false,代表MessageQueue是不允许退出的
        prepare(false);
        synchronized (Looper.class) {
            if (sMainLooper != null) {
                throw new IllegalStateException("The main Looper has already been prepared.");
            }
            sMainLooper = myLooper();
        }
    }

    /**
     * Returns the application's main looper, which lives in the main thread of the application.
     */
    public static Looper getMainLooper() {
        synchronized (Looper.class) {
            return sMainLooper;
        }
    }

常用的方法 prepare()创建一个looper对象,在其他线程中想具有消息循环功能这个方法就必须调用。
在Looper.prepare()方法中,调用了重载方法参数传的是true,表示是允许退出,在创建Looper对象的时候,会将Looper所属的当前线程是哪个缓存在Looper实例中

    public static void prepare() {
        prepare(true);
    }

    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed));
    }

    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }

在Looper实例中,通过调用其loop()方法,开始循环取出消息

public static void loop() {}

2.Handler的消息发送和处理过程分析

Handler 是负责把Message压入Queue中,还负责处理Message。Handler工作必须依赖Looper才行,没有Looper对象会抛出RuntimeException异常,不管是post sendMessage 还是延时的消息发送,最终都会到enqueueMessage方法中把消息传到缓冲区等待Looper处理。

创建Handler
    public Handler(@Nullable Callback callback, boolean async) {
        if (FIND_POTENTIAL_LEAKS) {
            final Class klass = getClass();
            if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
                    (klass.getModifiers() & Modifier.STATIC) == 0) {
                Log.w(TAG, "The following Handler class should be static or leaks might occur: " +
                    klass.getCanonicalName());
            }
        }
        // 获取当前线程中的Looper实例
        mLooper = Looper.myLooper();
        // 如果当前线程中的Looper对象为null,则抛出异常,从这里可以看出创建Handler对象
        // 当前线程就必须要先有Looper对象
        if (mLooper == null) {
            throw new RuntimeException(
                "Can't create handler inside thread " + Thread.currentThread()
                        + " that has not called Looper.prepare()");
        }
        // 每个Handler中使用的MessageQueue对象,都是从Looper对象中取出的
        // 一个线程只有一个Looper对象,可以有多少Handler对象
        // 所以一个线程中的多个Handler对象是共用一个MessageQueue的
        mQueue = mLooper.mQueue;
        mCallback = callback;
        mAsynchronous = async;
    }
创建Message

可以直接new Message,但是有更好的方式Message.obtain。因为可以检查是否可以有复用的Message用过复用避免过多的创建,销毁Message对象达到优化内存和性能的目的

    public static Message obtain(Handler h) {
        // 调用重载的obtain方法
        Message m = obtain();
        // 并绑定创建Message对象的Handler对象
        m.target = h;

        return m;
    }
    public static Message obtain() {
        // sPoolSync是一个Object对象,用来同步保证线程安全的
        synchronized (sPoolSync) {
            // sPool其实就是Handler.dispatchMessage后通过recycleUnchecked回收用以复用的Message
            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();
    }
Handler内部发送消息方法源码解析:

(1)sendMessage方法,内部调用的是sendMessageDelayed,只不过时间传0

public final boolean sendMessage(Message msg){
    return sendMessageDelayed(msg, 0);
}

(2)sendMessageDelayed

    public final boolean sendMessageDelayed(Message msg, long delayMillis){
        if (delayMillis < 0) {
            delayMillis = 0;
        }
        return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
    }
    //SystemClock.uptimeMillis()表示从开机到现在的毫秒数
    public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
        MessageQueue queue = mQueue;
        if (queue == null) {
            RuntimeException e = new RuntimeException(
                    this + " sendMessageAtTime() called with no mQueue");
            Log.w("Looper", e.getMessage(), e);
            return false;
        }
        return enqueueMessage(queue, msg, uptimeMillis);
    }
    // 将Message与发送Message的Handler做绑定
    private boolean enqueueMessage(MessageQueue queue, Message msg, long uptimeMillis) {
// 这部分,是对Message进行赋值,将当前的Handler对象赋值给Message.target
// 但是如果Message是采用obtain方法创建的,则在这个方法内部会对target赋值
        msg.target = this;
        if (mAsynchronous) {
            msg.setAsynchronous(true);
        }
        return queue.enqueueMessage(msg, uptimeMillis);
    }

在Handler的enqueueMessage方法中可以看出,每个Message实例,在这里会对其target赋值Handler实例,赋值的目的就是为了在Looper.loop()方法调用的时候用来在Looper.loop()方法中取出消息并且通过消息的target来将消息分发给对应的Handler。这里的Handler是在发送消息的时候,将Message与Handler先做个绑定,即将Handler实例保存在Message中的target属性中
注意:

System.currentTimeMillis()获取的时间,可以通过System.setCurrentTimeMillis(long)方法,进行修改,那么在某些情况下,一旦被修改,时间间隔就不准了,所以推荐使用SystemClock.uptimeMillis(),这样就可以保证消息队列中每个消息的时间顺序是准确的

MessageQueue内部消息入队处理

而MessageQueue的enqueueMessage,就是将消息入队的操作,MessageQueue是单向链表结构,是采用先入先出的操作来处理消息

    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) {
// 判断Looper是否有退出,这是在Looper.quit()方法中调用mQueue.quit(false);设置mQuitting为true的
            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;
// p相当于当前Message的head
            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循环寻找插入点,直到找到为null的时候,因为这个时候p为当前节点,而prev为前一个节点,找到为空的当前节点,然后在这个位置插入
            // for循环遍历Message队列,如果当前要插入的msg的时间
            // 大于当前遍历到的Message队列中的节点的时间
            // 则继续遍历,如果当前要插入的msg的时间when小于当前遍历到
            // 的节点p的时间when,则将消息插入到p节点之前
                for (;;) {
                    prev = p;
                    p = p.next;
                    if (p == null || when < p.when) {
                        break;
                    }
                    if (needWake && p.isAsynchronous()) {
                        needWake = false;
                    }
                }
                // 设置需要插入的Message的下一个节点为null
                // 设置前一个节点的下一个节点为Message
                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;
    }

这里的nativeWake,其实是调用了frameworks/base/core/jni/android_os_MessageQueue.cpp中的

static void android_os_MessageQueue_nativeWake(JNIEnv* env, jclass clazz, jlong ptr) {
    NativeMessageQueue* nativeMessageQueue = reinterpret_cast(ptr);
    nativeMessageQueue->wake();
}

而这里的NativeMessageQueue的wake()方法,其实就是在android_os_MessageQueue.cpp中实现的

void NativeMessageQueue::wake() {
    mLooper->wake();
}
Looper.loop()循环处理消息并分发

MessageQueue的出队操作,其实就是next()方法,返回一个Message。在线程中,创建Looper实例之后,通过调用Looper.loop()方法,循环从每个Looper实例中对应的MessageQueue消息缓存队列中读取消息,并且分发给Handler处理

    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循环
        for (;;) {
            if (nextPollTimeoutMillis != 0) {
                // 因为下一条Message尚未到处理时间,则会将等待过程中需要处理的内容交给CPU
                Binder.flushPendingCommands();
            }
            // 这里会有一个等待,在这个等待中设置了一个超时时间,即postDelayed等方式发送的延迟处理的消息,其实是通过等待一定的时间再继续执行的方式来进行
            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) {
// 如果当前的msg不为空,但是这个msg中的Handler为空,那么直接拿下一个消息,因为这个消息已经没有Handler来进行处理
                    // 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;
                        }
                        // 将当前消息的指向置为null
                        msg.next = null;
                        if (DEBUG) Log.v(TAG, "Returning message: " + msg);
                        msg.markInUse();
                        return msg;
                    }
                } else {
                    // No more messages.
                    nextPollTimeoutMillis = -1;
                }

                // Process the quit message now that all pending messages have been handled.
                if (mQuitting) {
                    dispose();
                    return null;
                }

                // If first time idle, then get the number of idlers to run.
                // Idle handles only run if the queue is empty or if the first message
                // in the queue (possibly a barrier) is due to be handled in the future.
                if (pendingIdleHandlerCount < 0
                        && (mMessages == null || now < mMessages.when)) {
                    pendingIdleHandlerCount = mIdleHandlers.size();
                }
                if (pendingIdleHandlerCount <= 0) {
                    // No idle handlers to run.  Loop and wait some more.
                    mBlocked = true;
                    continue;
                }

                if (mPendingIdleHandlers == null) {
                    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
                }
                mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
            }

            // Run the idle handlers.
            // We only ever reach this code block during the first iteration.
            for (int i = 0; i < pendingIdleHandlerCount; i++) {
                final IdleHandler idler = mPendingIdleHandlers[i];
                mPendingIdleHandlers[i] = null; // release the reference to the handler

                boolean keep = false;
                try {
                    keep = idler.queueIdle();
                } catch (Throwable t) {
                    Log.wtf(TAG, "IdleHandler threw exception", t);
                }

                if (!keep) {
                    synchronized (this) {
                        mIdleHandlers.remove(idler);
                    }
                }
            }

            // Reset the idle handler count to 0 so we do not run them again.
            pendingIdleHandlerCount = 0;

            // While calling an idle handler, a new message could have been delivered
            // so go back and look again for a pending message without waiting.
            nextPollTimeoutMillis = 0;
        }
    }

而在Looper的loop()轮循器中通过MessageQueue.next()方法取出消息

    public static void loop() {
        final Looper me = myLooper();
        if (me == null) {
            throw new RuntimeException("No Looper; Looper.prepare() wasn't called on this thread.");
        }
        final MessageQueue queue = me.mQueue;

        // Make sure the identity of this thread is that of the local process,
        // and keep track of what that identity token actually is.
        Binder.clearCallingIdentity();
        final long ident = Binder.clearCallingIdentity();

        // Allow overriding a threshold with a system prop. e.g.
        // adb shell 'setprop log.looper.1000.main.slow 1 && stop && start'
        final int thresholdOverride =
                SystemProperties.getInt("log.looper."
                        + Process.myUid() + "."
                        + Thread.currentThread().getName()
                        + ".slow", 0);

        boolean slowDeliveryDetected = false;

        for (;;) {
            // 调用MessageQueue的next()方法,取出下一次要处理的消息
            Message msg = queue.next(); // might block
            if (msg == null) {
                // No message indicates that the message queue is quitting.
                return;
            }

            // This must be in a local variable, in case a UI event sets the logger
            final Printer logging = me.mLogging;
            if (logging != null) {
                logging.println(">>>>> Dispatching to " + msg.target + " " +
                        msg.callback + ": " + msg.what);
            }

            final long traceTag = me.mTraceTag;
            long slowDispatchThresholdMs = me.mSlowDispatchThresholdMs;
            long slowDeliveryThresholdMs = me.mSlowDeliveryThresholdMs;
            if (thresholdOverride > 0) {
                slowDispatchThresholdMs = thresholdOverride;
                slowDeliveryThresholdMs = thresholdOverride;
            }
            final boolean logSlowDelivery = (slowDeliveryThresholdMs > 0) && (msg.when > 0);
            final boolean logSlowDispatch = (slowDispatchThresholdMs > 0);

            final boolean needStartTime = logSlowDelivery || logSlowDispatch;
            final boolean needEndTime = logSlowDispatch;

            if (traceTag != 0 && Trace.isTagEnabled(traceTag)) {
                Trace.traceBegin(traceTag, msg.target.getTraceName(msg));
            }

            final long dispatchStart = needStartTime ? SystemClock.uptimeMillis() : 0;
            final long dispatchEnd;
            try {
                // 获取到Message对象之后,调用这个消息对象中所保存的Handler对象,
                //然后通过Handler的dispatchMessage方法分发消息
                msg.target.dispatchMessage(msg);
                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
            if (logSlowDelivery) {
                if (slowDeliveryDetected) {
                    if ((dispatchStart - msg.when) <= 10) {
                        Slog.w(TAG, "Drained");
                        slowDeliveryDetected = false;
                    }
                } else {
                    if (showSlowLog(slowDeliveryThresholdMs, msg.when, dispatchStart, "delivery",
                            msg)) {
                        // Once we write a slow delivery log, suppress until the queue drains.
                        slowDeliveryDetected = true;
                    }
                }
            }
            if (logSlowDispatch) {
                showSlowLog(slowDispatchThresholdMs, dispatchStart, dispatchEnd, "dispatch", msg);
            }

            if (logging != null) {
                logging.println("<<<<< Finished to " + msg.target + " " + msg.callback);
            }

            // Make sure that during the course of dispatching the
            // identity of the thread wasn't corrupted.
            final long newIdent = Binder.clearCallingIdentity();
            if (ident != newIdent) {
                Log.wtf(TAG, "Thread identity changed from 0x"
                        + Long.toHexString(ident) + " to 0x"
                        + Long.toHexString(newIdent) + " while dispatching to "
                        + msg.target.getClass().getName() + " "
                        + msg.callback + " what=" + msg.what);
            }

            msg.recycleUnchecked();
        }
    }

在调用Looper.loop()方法处理消息的时候,会通过Message中缓存的每个消息对应的target(也就是对应的Handler实例)来发送给对应的Handler,因为在发送消息的时候会设置消息的target

Handler的dispatchMessage方法:

    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

而handleMessage就是我们在使用Handler的时候重写的那个方法

public void handleMessage(Message msg) {

}

在Handler的dispatchMessage方法中,如果实现了Handler的Callback接口,并且重写该接口的handleMessage方法,那么该方法一般需要返回为false,目的是为了执行Handler类中的handleMessage方法,如果不执行Handler类中的handleMessage方法,则可以返回为true,但是一般返回false

3.主线程创建Looper实例

在android应用程序进程启动过程中,由系统AMS向Zygote进程发送启动应用程序进程的请求,然后在Zygote接收到该请求之后,通过fock自身创建了应用程序进程,并且通过异常捕获处理的方式捕获ActivityThread.main方法,然后调用,在ActivityThread.main方法中,通过Looper.prepareMainLooper()创建主线程的Looper实例
Looper:
这是ActivityThread类:

    public static void main(String[] args) {
        Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "ActivityThreadMain");

        // CloseGuard defaults to true and can be quite spammy.  We
        // disable it here, but selectively enable it later (via
        // StrictMode) on debug builds, but using DropBox, not logs.
        CloseGuard.setEnabled(false);

        Environment.initForCurrentUser();

        // Set the reporter for event logging in libcore
        EventLogger.setReporter(new EventLoggingReporter());

        // Make sure TrustedCertificateStore looks in the right place for CA certificates
        final File configDir = Environment.getUserConfigDirectory(UserHandle.myUserId());
        TrustedCertificateStore.setDefaultUserDirectory(configDir);

        Process.setArgV0("");
// 创建Activity的Looper对象
        Looper.prepareMainLooper();

        ActivityThread thread = new ActivityThread();
        thread.attach(false);

        if (sMainThreadHandler == null) {
            sMainThreadHandler = thread.getHandler();
        }

        if (false) {
            Looper.myLooper().setMessageLogging(new
                    LogPrinter(Log.DEBUG, "ActivityThread"));
        }

        // End of event ActivityThreadMain.
        Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
// 调用Looper循环
        Looper.loop();

        throw new RuntimeException("Main thread loop unexpectedly exited");
    }

在创建主线程的Looper实例的时候,默认的quitAllowed是传了false,是不允许退出的。因为sMainLooper!=null的时候会抛出异常,说明每个线程就只能有一个Looper对象。

4.主线程为什么不会阻塞问题

Looper.loop()中的for循环实际上是阻塞了整个Android,而Android之所以不会阻塞,是因为Android是一个消息驱动机制,在ActivityThread中有一个H类对象,这个H类是Handler的子类,Android的所有事件都是通过H类接受到Message之后,然后通过Handler的handleMessage方法进行消息处理的。这个过程,就是在ActivityThread中的main方法中会创建一个ActivityThread对象,然后通过ActivityThread.getHandler就可以获得H对象,也就是Handler对象,这个对象就是在ActivityThread中创建的一个常量对象。

5.Handler导致的内存泄漏问题

Handler导致内存泄露的原因:
  • (1)因为定义的匿名内部类,会持有外部类的引用this,可以直接调用外部类的方法和属性。
  • (2)生命周期的问题。因为Handler.sendMessageAtTime会调用enqueueMessage,然后msg.target=this,说明Message会持有Handler,而Message在传递过程中,会有延时的情况,比如设置20s执行、20分钟执行,这样就会出现Message持有了Handler,而Handler持有了Activity,但是当Activity销毁的时候,可能Message还没处理,还在延迟等待,这样就导致Activity根据JVM可达性分析算法得出Activity不能被GC回收。

下面这段代码是一个内部类,在Java中内部类或者匿名内部类都会隐私的持有外部类对象,而在Android中使用Handler的一般都是Activity,这就导致如果handler还在执行中而actiivty finsh掉,activity就不能被正常销毁回收。进而GC的时候就导致JVM不能回收Activity,有可能多次操作后就OOM了。

解决办法:

(1)把内部类换成static, static不会隐式持有外部对象。
由于Handler不再持有外部类对象的引用,导致程序不允许你在Handler中操作Activity中的对象了。所以你需要在Handler中增加一个对Activity的弱引用

(2)一般Handler导致的内存泄漏都是因为,消息处理是异步的。finsh的时候消息还在处理等待状态,这个时候可以在activity finsh的时候把handler移除掉,调用removeCallbacks方法移除。

(3)关闭Activity的时候停掉你的后台线程。

如何避免在使用Handler的时候造成内存泄漏呢?

使用显形的引用,1.静态内部类。 2. 外部类
使用弱引用 2. WeakReference

两者同时使用

    private static class MyHandler extends Handler {  
        private final WeakReference mActivity;  
  
        public MyHandler(HandlerActivity2 activity) {  
            mActivity = new WeakReference(activity);  
        }  
  
        @Override  
        public void handleMessage(Message msg) {  
            System.out.println(msg);  
            if (mActivity.get() == null) {  
                return;  
            }  
            mActivity.get().todo();  
        }  
    }  

使用弱引用,其实就是将对应的Activity存在弱引用中。
并且在Activity被finish的时候,还要清空MessageQueue中的正在排队的消息。
在onDestroy中调用下面的方法清空
mHandler.removeCallbacksAndMessages(null);

Looper:
public void quit() {
    mQueue.quit(false);
}

MessageQueue:
void quit(boolean safe) {
    if (!mQuitAllowed) {
        throw new IllegalStateException("Main thread not allowed to quit.");
    }

    synchronized (this) {
        if (mQuitting) {
            return;
        }
        mQuitting = true;
        // 清除消息,这样消息队列为null,就会进入一个无限等待状态
        if (safe) {
            removeAllFutureMessagesLocked();
        } else {
            removeAllMessagesLocked();
        }

        // 唤醒等待
        nativeWake(mPtr);
    }
}

6.子线程中维护的Looper,消息队列无消息的时候处理方法是什么?有什么用?

必须要调用Looper.quit()或者quitSafely(),会把mQuitting赋值为true,会把所有的消息全部清空,然后调用nativeWake(mPtr),唤醒。唤醒是因为清空消息的时候,消息队列为null,而Looper.loop()方法依然会在循环取出消息,就会陷入一个无限等待状态,那么就需要唤醒,在next()方法中退出无限死循环,直接调用return null返回一个空的null,返回空的null的时候,在Looper.loop()方法中就会结束。
因为消息队列无消息的时候,主动调用Looper.quit(),其实就会调用MessageQueue的quit方法。
MessageQueue.quit()

    void quit(boolean safe) {
        if (!mQuitAllowed) {
            throw new IllegalStateException("Main thread not allowed to quit.");
        }

        synchronized (this) {
            if (mQuitting) {
                return;
            }
            // 将正在退出的标志置为true,这样在MessageQueue.next取出消息的时候,就可以将消息返回一个null
            // 而在Looper.loop()遍历消息的时候,当取出的消息为null的时候,就直接return
            mQuitting = true;
            // 清空消息队列
            if (safe) {
                removeAllFutureMessagesLocked();
            } else {
                removeAllMessagesLocked();
            }

            // 唤醒消息队列,这样做的目的是消息队列为null的时候,MessageQueue是处于阻塞状态
            // 而这里唤醒的目的就是为了在next方法中返回一个空消息给Looper.loop()进行处理
            nativeWake(mPtr);
        }
    }

7.线程同步问题

Handler机制中最主要的类MessageQueue,这个类是所有消息的存储队列,是采用优先级队列的方式存储消息,而MessageQueue类中主要的就是消息入队和出队,分别是enqueueMessage和next方法,这两个方法中,都是采用的synchronized关键字代码块的方式来保证消息同步的,传入的锁是this,即对象锁,MessageQueue对象锁,因为一个线程对应一个Looper,而一个Looper对应一个MessageQueue,所以一个线程中不管多少个Handler发送和处理消息,最终都是通过synchronized同步代码块保证消息的入队和出队的同步,保证线程安全。这对于在调用同一个MessageQueue的handler对象来说,他们是在同一个线程的,而在这个线程内,入队和出队都是互斥的。并且因为一个线程只有一个Looper对象,一个Looper对象对应一个MessageQueue,所以在一个线程内,不管有多少个Handler对象一次都只会处理一个消息,因为在Looper.loop()循环遍历消息的时候,每次就只能同步出去一个消息。

四、四种引用

强引用(一般垃圾回收器不回收被强引用的对象)
在一般的Java程序中,见到最多的就是强引用(strong reference)。如Date date = new Date(),date就是一个对象的强引用。对象的强引用可以在程序中到处传递。很多情况下,会同时有多个引用指向同一个对象。强引用的存在限制了对象在内存中的存活时间。假如对象A中包含了一个对象B的强引用,那么一般情况下,对象B的存活时间就不会短于对象A。如果对象A没有显式的把对象B的引用设为null的话,就只有当对象A被垃圾回收之后,对象B才不再有引用指向它,才可能获得被垃圾回收的机会。

软引用 (内存不足的时候,对象被回收)
软引用(soft reference)在强度上弱于强引用,通过类SoftReference来表示。它的作用是告诉垃圾回收器,程序中的哪些对象是不那么重要,当内存不足的时候是可以被暂时回收的。当JVM中的内存不足的时候,垃圾回收器会释放那些只被软引用所指向的对象。如果全部释放完这些对象之后,内存还不足,才会抛出OutOfMemory错误。软引用非常适合于创建缓存。当系统内存不足的时候,缓存中的内容是可以被释放的。

弱引用 (回收器只要发现一个对象的引用是全部是弱引用,就会回收此对象、释放内存)
弱引用(weak reference)在强度上弱于软引用,通过类WeakReference来表示。它的作用是引用一个对象,但是并不阻止该对象被回收。如果使用一个强引用的话,只要该引用存在,那么被引用的对象是不能被回收的。弱引用则没有这个问题。在垃圾回收器运行的时候,如果一个对象的所有引用都是弱引用的话,该对象会被回收。

Handler中使用弱引用来保存Activity对象,就是因为Activity对象如果在Handler执行过程中被销毁回收,那么如果不使用弱引用,这时Activity在Handler中就是属于强引用,则不会被回收,这样就会造成了内存泄漏,而使用弱引用的话,就不会阻止Handler中的Activity对象被回收。

五、Handler.postDelayed实现原理

这部分是对上面Handler原理的加以说明

1.Handler.postDelayed方法其方法内部,调用的是Handler的sendMessageDelayed方法:

public final boolean postDelayed(Runnable r, long delayMillis){
    return sendMessageDelayed(getPostMessage(r), delayMillis);
}

2.看下sendMessageDelayed源码:

public final boolean sendMessageDelayed(Message msg, long delayMillis){
    if (delayMillis < 0) {
        delayMillis = 0;
    }
    return sendMessageAtTime(msg, SystemClock.uptimeMillis() + delayMillis);
}

从这个方法中可以看出,延迟时间其实是在SystemClock.uptimeMillis()这个时间的基础上,加上延迟时间的,SystemClock.uptimeMillis()是从系统开机启动到现在的时间,而且不包括休眠时间,因此这是一个相对时间。
用这样的方式,而不是用当前时间,主要也是因为Handler会受到阻塞、挂起状态、睡眠等,这些时候是不应该执行的。

3.sendMessageAtTime

public boolean sendMessageAtTime(Message msg, long uptimeMillis) {
    MessageQueue queue = mQueue;
    if (queue == null) {
        RuntimeException e = new RuntimeException(
        this + " sendMessageAtTime() called with no mQueue");
        Log.w("Looper", e.getMessage(), e);
        return false;
    }
    return enqueueMessage(queue, msg, uptimeMillis);
}

这个方法做的工作,就是将Message消息存放到MessageQueue中,但是并没有做延迟存放的操作。存放的这个过程传入uptimeMillis时间,主要是为了对所有的message做排序,按需要执行的顺序将message排序放好,以便在next方法中顺序取出。
上面三个步骤是存放Message的,但是并没有做任何延迟的处理,那么延迟的操作则不是在存的时候进行的,那么只有可能是在取message的时候做了延迟处理

而上面关于Handler的消息处理分发部分的Looper.loop()的源码解析可以看出,loop方法内部,并没有等待或者阻塞等操作,而只有MessageQueue的next方法有一个注释:可能会阻塞,那么看MessageQueue的next方法

4.MessageQueue的next()方法

在MessageQueue中,有一个是否阻塞的标志位,这个是用来判断是否在pollOnce()的时候被阻塞等待了。

    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循环
        for (;;) {
            if (nextPollTimeoutMillis != 0) {
                // 因为下一条Message尚未到处理时间,则会将等待过程中需要处理的内容交给CPU
                Binder.flushPendingCommands();
            }
            // 这里会有一个等待,在这个等待中设置了一个超时时间,即postDelayed等方式发送的延迟处理的消息,其实是通过等待一定的时间再继续执行的方式来进行
            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) {
// 如果当前的msg不为空,但是这个msg中的Handler为空,那么直接拿下一个消息,因为这个消息已经没有Handler来进行处理
                    // 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;
                        }
                        // 将当前消息的指向置为null
                        msg.next = null;
                        if (DEBUG) Log.v(TAG, "Returning message: " + msg);
                        msg.markInUse();
                        return msg;
                    }
                } else {
                    // No more messages.
                    nextPollTimeoutMillis = -1;
                }

                // Process the quit message now that all pending messages have been handled.
                if (mQuitting) {
                    dispose();
                    return null;
                }

                // If first time idle, then get the number of idlers to run.
                // Idle handles only run if the queue is empty or if the first message
                // in the queue (possibly a barrier) is due to be handled in the future.
                if (pendingIdleHandlerCount < 0
                        && (mMessages == null || now < mMessages.when)) {
                    pendingIdleHandlerCount = mIdleHandlers.size();
                }
                if (pendingIdleHandlerCount <= 0) {
                    // No idle handlers to run.  Loop and wait some more.
                    mBlocked = true;
                    continue;
                }

                if (mPendingIdleHandlers == null) {
                    mPendingIdleHandlers = new IdleHandler[Math.max(pendingIdleHandlerCount, 4)];
                }
                mPendingIdleHandlers = mIdleHandlers.toArray(mPendingIdleHandlers);
            }

            // Run the idle handlers.
            // We only ever reach this code block during the first iteration.
            for (int i = 0; i < pendingIdleHandlerCount; i++) {
                final IdleHandler idler = mPendingIdleHandlers[i];
                mPendingIdleHandlers[i] = null; // release the reference to the handler

                boolean keep = false;
                try {
                    keep = idler.queueIdle();
                } catch (Throwable t) {
                    Log.wtf(TAG, "IdleHandler threw exception", t);
                }

                if (!keep) {
                    synchronized (this) {
                        mIdleHandlers.remove(idler);
                    }
                }
            }

            // Reset the idle handler count to 0 so we do not run them again.
            pendingIdleHandlerCount = 0;

            // While calling an idle handler, a new message could have been delivered
            // so go back and look again for a pending message without waiting.
            nextPollTimeoutMillis = 0;
        }
    }

在这里重复一遍关于 MessageQueue.next()方法
当nextPollTimeoutMillis是大于0的时候,那么下一次循环的时候会调用nativePollOnce方法,让队列阻塞。但是如果当前的队列是阻塞的,这个时候加入了一个不是延迟发送的message的时候,就会将这个message加入队首,然后主动唤醒队列,处理这个消息

六、自定义手写Handler:

Handler实际上就是一个生产者与消费者模式。

public class Handler {

    private MessageQueue mQueue;

    public Handler() {
        Looper mLooper = Looper.myLooper();
        mQueue = mLooper.mQueue;
    }

    /**
     * 发送消息,加入队列
     * @param msg
     */
    public void sendMessage(Message msg){
        msg.target = this;
        // 传入消息
        mQueue.enqueueMessage(msg);
    }

    /**
     * 处理消息
     * @param msg
     */
    public void handleMessage(Message msg){

    }

    /**
     * 分发消息
     * @param msg
     */
    public void dispatchMessage(Message msg){
        handleMessage(msg);
    }
}

Message类:

public class Message {
    // Message在使用Handler发送消息的时候,将Handler赋值给对应的Message
    //用于在Looper.loop()获取消息之后,通过Handler实例分发消息
    Handler target;

    public Object obj;

    public int what;

    public Message() {
    }

    @Override
    public String toString() {
        return obj.toString();
    }
}

MessageQueue类:

public class MessageQueue {

    private Message[] items;

    // 入队和出队的索引位置
    private int putIndex;
    private int takeIndex;

    // 计数器
    private int count;

    private Lock lock;

    private Condition notEmpty;
    private Condition notFull;

    public MessageQueue() {
        items = new Message[50];

        // 可重入锁
        lock = new ReentrantLock();

        notEmpty = lock.newCondition();
        notFull = lock.newCondition();
    }

    /**
     * 取出消息
     *
     * @return
     */
    public Message next() {
        Message msg = null;
        try {
            lock.lock();
            // 如果消息队列为null,则等待新消息的入队
            while (count == 0) {
                notEmpty.await();
            }
            msg = items[takeIndex];
            items[takeIndex] = null;
            takeIndex = (++takeIndex == items.length) ? 0 : takeIndex;
            count--;
            // 已经消费了一个消息,可以继续入队
            notFull.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return msg;
    }

    /**
     * 加入队列
     *
     * @param msg
     */
    public void enqueueMessage(Message msg) {
        // 使用while循环,这样的话,就可以避免不需要唤醒的子线程继续等待。因为是唤醒了全部,有可能唤醒了不需要被唤醒的子线程
        // 但是如果是使用if,则只会等待一次
        try {
            lock.lock();
            // 如果消息队列已满,则等待
            while (count == 50) {
                notFull.await();
            }
            items[putIndex] = msg;
            putIndex = (++putIndex == items.length) ? 0 : putIndex;
            count++;
            // 如果消息队列不为null,则可以取出消息
            notEmpty.signalAll();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }

    }
}

Looper类:

public class Looper {

    public MessageQueue mQueue;
    static ThreadLocal sThreadLocal = new ThreadLocal<>();

    private Looper(){
        mQueue = new MessageQueue();
    }

    /**
     * 初始化Looper对象
     */
    public static void prepare(){
        if (sThreadLocal.get() != null){
            throw new RuntimeException("一个线程只能有一个looper");
        }
        sThreadLocal.set(new Looper());
    }

    /**
     * 获取当前线程的Looper对象
     * @return
     */
    public static Looper myLooper(){
        return sThreadLocal.get();
    }

    public static void loop(){
        Looper me = myLooper();

        if (me == null){
            throw new RuntimeException("当前线程无Looper对象");
        }

        MessageQueue messageQueue = me.mQueue;
        for (;;){
            Message msg = messageQueue.next();
            if (msg != null){
                msg.target.dispatchMessage(msg);
            }
        }
    }
}

七、new Handler()两种方式

    private Handler mHandler1 = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            return false;
        }
    });
    private Handler mHandler2 = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
        }
    };

一种是通过Handler的无参构造器来创建,一种是通过有参构造器来创建。

    /**
     * Handle system messages here.
     */
    public void dispatchMessage(Message msg) {
        if (msg.callback != null) {
            handleCallback(msg);
        } else {
            if (mCallback != null) {
                if (mCallback.handleMessage(msg)) {
                    return;
                }
            }
            handleMessage(msg);
        }
    }

在Handler中,是在dispatchMessage中来分发消息的,而这里的分发消息,是首先判断mCallback是否为空来执行的。

为什么使用Handler消息机制可以跨进程?

因为在同一个进程里,内存是共享的,Looper对象创建在主线程,Handler对象创建在主线程,然后再子线程中使用这个Handler对象发送消息,因为MessageQueue是在Looper对象中的,而Looper对象是在主线程中创建的,而且Handler对象是在主线程中创建的,所以Handler对象的handleMessage方法是在主线程中执行的,又因为Looper.loop()是在主线程中执行的,每次都是轮循MessageQueue获取Message,然后通过主线程的Handler对象的dispatchMessage分发,发送到handleMessage。

八、Handler内存泄露的原因?为什么其他的内部类没有说过这个问题?

(1)因为定义的匿名内部类,会持有外部类的引用this,可以直接调用外部类的方法和属性。
(2)生命周期的问题。因为Handler.sendMessageAtTime会调用enqueueMessage,然后msg.target=this,说明Message会持有Handler,而Message在传递过程中,会有延时的情况,比如设置20s执行、20分钟执行,这样就会出现Message持有了Handler,而Handler持有了Activity,但是当Activity销毁的时候,可能Message还没处理,还在延迟等待,这样就导致Activity根据JVM可达性分析算法得出Activity不能被GC回收。

https://www.jianshu.com/p/e6877401a0e2

九、Handler#runWithScissors

在创建WMS对象的时候,WMS的main方法中就通过调用DisplayThread.getHandler().runWithScissors()方法创建。
WMS的main方法是在SystemServer进程的主线程调用的,然后在调用WMS的main方法的时候,通过DisplayThread这个HandlerThread,实现异步处理,而这里的异步处理,其实是通过跨线程的一个同步,即通过DisplayThread中的Handler对象,调用runWithScissors方法,该方法其实是可以实现发送消息等待消息处理完成之后再继续执行runWithScissors方法调用位置之后的代码,即等待消息处理完之后再进行return WMS对象。

public static WindowManagerService main(final Context context, final InputManagerService im,
        final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
        ActivityTaskManagerService atm) {
    return main(context, im, showBootMsgs, onlyCore, policy, atm,
            SurfaceControl.Transaction::new);
}
@VisibleForTesting
public static WindowManagerService main(final Context context, final InputManagerService im,
        final boolean showBootMsgs, final boolean onlyCore, WindowManagerPolicy policy,
        ActivityTaskManagerService atm, TransactionFactory transactionFactory) {
    // 这里其实就是在DisplayThread线程处理WMS的初始化
    DisplayThread.getHandler().runWithScissors(() ->
            sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy,
                    atm, transactionFactory), 0);
    return sInstance;
}

1.Handler#runWithScissors

根据上面的调用,上面的runWithScissors传入的就是一个Runnable实例,只不过是采用了lambda表达式的做法,所以Runnable的run()方法的方法体是就是:
sInstance = new WindowManagerService(context, im, showBootMsgs, onlyCore, policy, atm, transactionFactory), 0);

public final boolean runWithScissors(@NonNull Runnable r, long timeout) {
    if (r == null) {
        throw new IllegalArgumentException("runnable must not be null");
    }
    if (timeout < 0) {
        throw new IllegalArgumentException("timeout must be non-negative");
    }
    // 如果调用runWithScissors方法的线程是与消息处理线程在同一个线程
    // 则直接执行Runnable的run方法。
    if (Looper.myLooper() == mLooper) {
        r.run();
        return true;
    }
    // 如果调用runWithScissors方法的线程与消息处理线程不是同一个,则创建一个BlockingRunnable
    BlockingRunnable br = new BlockingRunnable(r);
    // 并且调用BlockingRunnable.postAndWait方法
    // 这里的返回值会先等待,等待DisplayThread线程中的Handler处理完
    // 消息之后,然后唤醒BlockingRunnable
    // 该Handler处理消息是在DisplayThread线程,而BlockingRunnable
    // 而BlockingRunnable调用wait并不会让DisplayThread线程中的
    // Handler等待,Handler依然会处理消息,处理消息其实就是调用了
    // BlockingRunnable.run()方法,当BlockingRunnable.run()执行完成
    // 就会调用notifyAll唤醒BlockingRunnable,执行postAndWait的return
    return br.postAndWait(this, timeout);
}

2.BlockingRunnable

private static final class BlockingRunnable implements Runnable {
    private final Runnable mTask;
    private boolean mDone;

    public BlockingRunnable(Runnable task) {
        mTask = task;
    }

    @Override
    public void run() {
        try {
            // 这个mTask其实就是runWithScissors中传入的Runnable对象
            // BlockingRunnable的run方法的执行,其实就是需要Handler遍历到消息处理的时候
            // 然后处理这个BlockingRunnable消息,在处理BlockingRunnable消息
            // 的时候,就会处理runWithScissors的参数中的Runnable这个mTask
            // 处理完成之后,就会调用notifyAll唤醒等待线程,然后执行postAndWait的return
            // 因为BlockingRunnable的run方法是由Handler处理消息
            // 这个消息的处理与BlockingRunnable是在不同的线程
            // 所以BlockingRunnable等待的时候,其run方法是可以由handler消息处理
            mTask.run();
        } finally {
            synchronized (this) {
                mDone = true;
                notifyAll();
            }
        }
    }

    public boolean postAndWait(Handler handler, long timeout) {
        // 调用postAndWait的时候,先调用handler对象的post将消息发送出
        // 如果入队成功,则为true,则开始阻塞
        if (!handler.post(this)) {
            return false;
        }
        // 在上面的方法调用中,timeout=0,则阻塞。
        synchronized (this) {
            if (timeout > 0) {
                final long expirationTime = SystemClock.uptimeMillis() + timeout;
                // 如果mDone为false的时候,则会等待,只有为true的时候,会执行
                while (!mDone) {
                    long delay = expirationTime - SystemClock.uptimeMillis();
                    if (delay <= 0) {
                        return false; // timeout
                    }
                    try {
                        wait(delay);
                    } catch (InterruptedException ex) {
                    }
                }
            } else {
                while (!mDone) {
                    try {
                        wait();
                    } catch (InterruptedException ex) {
                    }
                }
            }
        }
        return true;
    }
}

你可能感兴趣的:(Android-Handler源码)