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工作原理的主要内容,如果未能解决你的问题,请参考以下文章