码迷,mamicode.com
首页 > 其他好文 > 详细

Looper工作原理

时间:2018-10-15 00:36:57      阅读:474      评论:0      收藏:0      [点我收藏+]

标签:time   run   enabled   失败   一个   pat   err   java   ext   

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工作原理

标签:time   run   enabled   失败   一个   pat   err   java   ext   

原文地址:https://www.cnblogs.com/coconna/p/9788881.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!