Looper工作原理

Posted coconna

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Looper工作原理相关的知识,希望对你有一定的参考价值。

Looper在消息循环中扮演着消息循环的角色,他会不停的从MessageQueue中取出Message,如果有消息就处理,没有就会一直阻塞.

创建Looper

在创建Looper的时候会创建一个MessageQueue
    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed);
        mThread = Thread.currentThread();
    }
Looper为我们提供了prepare来创建对象.loop开启消息循环.

使用Looper

new Thread(new Runnable() {
            @Override
            public void run() {
                Looper.prepare();
                Handler handler = new Handler();
                Looper.loop();
            }
        }).start();
Looper提供了quit和quitSafely来安全退出.其中quit会立马退出,而quitSafely则会将消息都处理完成之后然后退出.当Looper退出后再通过Handler发送消息会失败,send方法返回false.建议所有的消息都处理完成之后使用quit来退出Looper否则线程会一直处于等待状态.

Looper工作原理

 public static void loop() {
        ...
        for (;;) {
            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 {
                msg.target.dispatchMessage(msg);
                dispatchEnd = needEndTime ? SystemClock.uptimeMillis() : 0;
            } finally {
                if (traceTag != 0) {
                    Trace.traceEnd(traceTag);
                }
            }
            ...

            msg.recycleUnchecked();
        }
    }
loop方法是一个死循环,跳出循环的方法就是queue.next返回了null.当Looper的quit被调用时,Looper会调用MessageQueue的quit会被调用,队列会被标记为退出状态.他的next方法就会返回null.[4]行
如果获取到了Message,就会调用msg.target.dispatchMessage(msg);其中msg.target就是Handler,所以会dispatchMessage会在创建Handler的线程中调用.这样就完成了线程的切换.[37]行

以上是关于Looper工作原理的主要内容,如果未能解决你的问题,请参考以下文章

Handler的工作原理。为啥在子线程中使用Handler会抛出异常

Handle的原理代码实现

Android的handler机制的原理?

Looper quit 的原理和细节

android handler 调用原理

handler机制的原理