Android13 Looper prepare流程分析

将当前线程初始化为循环器,代码如下:

//freameworks/base/core/java/android/os/Looper.java
public final class Looper {
    public static void prepare() {
        prepare(true);
    }
}

调用重载方法prepare:

//frameworks/base/core/java/android/os/Looper.java
public final class Looper {
    final MessageQueue mQueue;
    final Thread mThread;
    private Looper(boolean quitAllowed) {
        mQueue = new MessageQueue(quitAllowed); //创建消息对了
        mThread = Thread.currentThread(); //获取当前Thread
    }
}

通过new的方式创建Looper,Looper的构造方法如下:

//freameworks/base/core/java/android/os/Looper.java
public final class Looper {
    static final ThreadLocal<Looper> sThreadLocal = new ThreadLocal<Looper>();
    private static void prepare(boolean quitAllowed) {
        if (sThreadLocal.get() != null) {
            throw new RuntimeException("Only one Looper may be created per thread");
        }
        sThreadLocal.set(new Looper(quitAllowed)); //创建Looper,然后调用ThreadLocal的set方法设置到ThreadLocal中
    }
}

通过new的方式创建消息队列,MessageQueue的构造方法如下:

//frameworks/base/core/java/android/os/MessageQueue.java
public final class MessageQueue {
    MessageQueue(boolean quitAllowed) {
        mQuitAllowed = quitAllowed;
        mPtr = nativeInit();
    }
}

调用nativeInit方法,nativeInit是一个native方法,实现如下:

//frameworks/base/core/jni/android_os_MessageQueue.cpp
static jlong android_os_MessageQueue_nativeInit(JNIEnv* env, jclass clazz) {
    NativeMessageQueue* nativeMessageQueue = new NativeMessageQueue();
    if (!nativeMessageQueue) {
        jniThrowRuntimeException(env, "Unable to allocate native queue");
        return 0;
    }


    nativeMessageQueue->incStrong(env); //增加对象的强引用计数
    return reinterpret_cast<jlong>(nativeMessageQueue);
}

上面方法的主要处理如下:

1、通过new的方式创建NativeMessageQueue对象。

2、调用nativeMessageQueue的incStrong方法。

new NativeMessageQueue

下面分别进行分析:

//frameworks/base/core/jni/android_os_MessageQueue.cpp
class NativeMessageQueue : public MessageQueue, public LooperCallback {
    NativeMessageQueue::NativeMessageQueue() :
            mPollEnv(NULL), mPollObj(NULL), mExceptionObj(NULL) {
        mLooper = Looper::getForThread();
        if (mLooper == NULL) {
            mLooper = new Looper(false); 
            Looper::setForThread(mLooper); 
        }
    }
}

调用Looper的getForThread方法获取Looper对象,如果Looper对象为空就通过new的方式创建一个,然后调用Looper的setForThread方法设置对应的Looper:

class Looper : public RefBase {}
//system/core/libutils/Looper.c
sp<Looper> Looper::getForThread() {
    int result = pthread_once(& gTLSOnce, initTLSKey); //thread_once函数的作用是确保initTLSKey函数只被执行一次。
    LOG_ALWAYS_FATAL_IF(result != 0, "pthread_once failed");


    Looper* looper = (Looper*)pthread_getspecific(gTLSKey); //用于获取线程中gTLSKey的值
    return sp<Looper>::fromExisting(looper);
}

new Looper

Looper的构造方法如下:

//system/core/libutils/Looper.c
Looper::Looper(bool allowNonCallbacks)
    : mAllowNonCallbacks(allowNonCallbacks),
      mSendingMessage(false),
      mPolling(false),
      mEpollRebuildRequired(false),
      mNextRequestSeq(WAKE_EVENT_FD_SEQ + 1),
      mResponseIndex(0),
      mNextMessageUptime(LLONG_MAX) {
    mWakeEventFd.reset(eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC));
    LOG_ALWAYS_FATAL_IF(mWakeEventFd.get() < 0, "Could not make wake event fd: %s", strerror(errno));


    AutoMutex _l(mLock);
    rebuildEpollLocked();
}

到这里Looper的prepare流程就分析完了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值