Android消息机制剖析—Looper篇
来源:互联网 发布:湖人12年纳什数据 编辑:程序博客网 时间:2024/06/08 22:50
本篇文章在android6.0基础上分析。
Looper在消息机制中扮演的角色是创造无限循环从Messagequeue中取得消息然后分发。
一、Looper的创建
只要调用Looper.prepare()方法之后,然后再Looper.loop()即可,这里两个方法都是static方法,表面没有任何Looper对象的参与,具体如何
先来看下prepare()这个方法:
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");//限制Looper.prepare()只能调用一次 } sThreadLocal.set(new Looper(quitAllowed));//这里才是Looper对象的创建,放入sThreadLocal中 }
<pre name="code" class="java"> private Looper(boolean quitAllowed) { mQueue = new MessageQueue(quitAllowed);//创造了Messagequeue mThread = Thread.currentThread(); }
代码中提到了sThreadLocal变量,类型为ThreadLocal,ThreadLocal的特殊作用在:可以多个线程共享,但set和get的作用域都是线程内的。例如thread-1和thread-2两个线程都调用了Loop.prepare(),使用的ThreadLocal是同一个对象,但set()放入的Looper是分别属于各自的。
二、Looper的loop()
先看源码,核心的地方被我加了注释。
public static void loop() { final Looper me = myLooper();//从ThreadLocal中获取本线程的Looper对象,这个对象是用Looper.prepare创建的 if (me == null) {//如果没有Looper.prepare,就调用了loop就会抛出下面的异常 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(); for (;;) {//最重要的就是这个死循环,4.0之前是while(true) Message msg = queue.next(); // might block,MessageQueue没有消息,执行next()就会线程阻塞,直到有消息为止。 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 Printer logging = me.mLogging; if (logging != null) { logging.println(">>>>> Dispatching to " + msg.target + " " + msg.callback + ": " + msg.what); } msg.target.dispatchMessage(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(); } }
这个Loop是消息机制的核心所在,尤其是for(;;)这个死循环;上面代码关注四个点:
(1)调用myLooper来判断是否已经用Looper.prepare()创建了Looper对象(ThreadLocal保存)
(2)Loop循环每次都会从MessageQueue中获取一个Message(next()方法),如果没有则线程阻塞。
(3)如果获取了一个Message,则调用target(Hanlder)的dispatchMessage方法来分派处理这个Message。
(4)最后调用msg.recycleUnchecked(),来格式化这个Message,重新进入消息池;
public static @Nullable Looper myLooper() { return sThreadLocal.get();//如果是线程thread-1调用,则获得的thread-1的Looper,如果是thread-2调动,获得的是thread-2的looper。 }
0 0
- Android消息机制剖析—Looper篇
- Android 消息机制之 handler、messageQueue、looper深入剖析
- Android消息机制 — Handler-Looper-MessageQueue
- android消息处理机制-------Looper
- Android消息机制之Looper
- Android消息机制之一---Looper
- android消息处理机制--Looper
- Android消息处理机制:源码剖析Handler、Looper,并实现图片异步加载
- android 消息机制,handler机制,messageQueue,looper
- Android Looper And Hander 机制剖析 - 01
- Android Looper And Hander 机制剖析 - 02
- Android Looper And Hander 机制剖析 - 03
- Android消息机制原理剖析—Handler篇
- android的消息处理机制——Looper,Handler,Message
- Android的消息处理机制——looper&handler&Message
- Android消息处理机制——Looper,Handler,Message,MessageQueue
- android的消息处理机制——Looper,Handler,Message
- Android消息处理机制—— Looper, Handler, Message
- iOS微信支付
- Java正则表达式:Pattern类和Matcher类
- leetcode_c++:Best Time to Buy and Sell Stock II(122)
- 斯坦福大学CS224d基础1:线性代数回顾
- ContentProvider的理解与使用
- Android消息机制剖析—Looper篇
- U-BOOT环境变量的获取和保存的实现分析
- leetcode_c++:Best Time to Buy and Sell Stock III(123)
- Jenkins+Maven+SVN快速搭建持续集成环境
- 英文文字游戏
- 9. Palindrome Number
- redis在windows64位操作系统的安装与使用
- erlang 导入库脚本
- u-boot与linux内核间的参数传递过程分析