安卓Looper源码总结
Posted 阳光照不到的王国
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了安卓Looper源码总结相关的知识,希望对你有一定的参考价值。
Looper
源码位置
Looper.java源码路径为:
android-rk3399/frameworks/base/core/java/android/os/Looper.java
prepare()函数
通过prepare函数可以得知,在一个线程中只会存在一个Looper对象。当多次调用prepare函数时会抛出以下异常。
private static void prepare(boolean quitAllowed)
if (sThreadLocal.get() != null) //通过prepare函数可以知道一个线程中只能存在一个Looper对象,否则会抛出以下异常
throw new RuntimeException("Only one Looper may be created per thread");
//通过ThreadLocal存放一个Looper对象;
sThreadLocal.set(new Looper(quitAllowed));
在主线程中,调用的是prepareMainLooper函数。
我们之所以在activity中不调用prepare()函数就可以直接使用Handler,是因为ActivityThread类的main函数已经帮我们间接调用了prepare函数。ActivityThread的main函数如下图:
Looper()构造函数
在Looper的构造函数中创建一个MessageQueue对象,并获取当前线程对象。源码如下:
private Looper(boolean quitAllowed)
mQueue = new MessageQueue(quitAllowed);
mThread = Thread.currentThread();
Loop()函数
Looper通过loop()函数中的死循环不断的从MessageQueue中获取Message,然后调用message.target也就是Handler来调度信息。
public static void loop()
/**
* public static @Nullable Looper myLooper()
* return sThreadLocal.get();
*
* 通过myLooper()函数来获取Looper对象。
*/
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;
//...此处省去多余代码
for (;;)
Message msg = queue.next(); // might block
if (msg == null)
// No message indicates that the message queue is quitting.
return;
//...此处省去多余代码
try
//通过msg.target获取Handler对象,然后通过handler对象来调度信息
msg.target.dispatchMessage(msg);
finally
if (traceTag != 0)
Trace.traceEnd(traceTag);
//...此处省去多余代码
在看源码的时候对ThreadLocal不是很熟悉,特意去看了下实现逻辑;大致整理一下:
ThreadLocal采用的是Map方式将当前线程作为key来存放对象,set函数如下:
Looper的源码到此分析结束,最主要的功能在loop()函数中。
以上是关于安卓Looper源码总结的主要内容,如果未能解决你的问题,请参考以下文章
Handler的创建Message的处理与Looper的作用——源码分析
Handler的创建Message的处理与Looper的作用——源码分析