安卓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函数。

image-20211229200348302

我们之所以在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()函数中。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

無昂博奥

测试下大赏功能,请勿大赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值