AHandler系列
【android12】【AHandler】【1.AHandler异步无回复消息原理篇】-CSDN博客
【android12】【AHandler】【2.AHandler异步回复消息原理篇】-CSDN博客
【android12】【AHandler】【3.AHandler原理篇AHandler类方法全解】-CSDN博客
其他系列
1.简介
前面我们主要介绍了有回复和无回复的消息的使用方法和源码解析,为了更好的理解Ahandler这个类的作用,本篇便主要对AHandler类的所有方法进行全解。
简单介绍一下Ahandler机制
AHandler是Android native层实现的一个异步消息机制,在这个机制中所有的处理都是异步的,将消息封装到一个消息AMessage结构体中,然后放到消息队列中去,后台专门有一个线程ALooper会从这个队列中取出消息然后分发执行,执行函数就是AHandler实例的onMessageReceived。
在AHandler中的消息分为不需要回复的消息和需要回复的消息。
不需要回复的消息:当被post到消息队列后,Alooper会从消息队列中取出消息,并发送给相应的Ahandler的onMessageReceived进行处理。
需要回复的消息:当被post到消息队列后,Alooper会从消息队列中取出消息,并发送给相应的Ahandler的onMessageReceived进行处理,处理完后,Ahandler会将想回复的消息返回给发送方,发送方接受返回的response消息。
1.1 主要类及其作用
**AHandler:**处理类,用于消息的处理,有一个纯虚函数onMessageReceived,一般需要继承此类并重写此方法,用于接受和处理消息。
AMessage:消息类,用于构建各种消息,通过post方法将消息发送给Alooper
**Alooper:**轮询类,用于保存消息队列,然后将消息发送到对应的AHandler
AReplyToken:这类似一个标识,表示要回复的是哪一条消息
1.2 Alooper类图
2.源码解析
2.1 Alooper类
cpp
//Alooper.h分析
struct ALooper : public RefBase {
typedef int32_t event_id;
typedef int32_t handler_id;
ALooper();
void setName(const char *name);//设置looper的名称
handler_id registerHandler(const sp<AHandler> &handler);//注册Handler,用map保存hadnler_id和handler信息
void unregisterHandler(handler_id handlerID);//取消注册handler
status_t start(bool runOnCallingThread = false,bool canCallJava = false,int32_t priority = PRIORITY_DEFAULT);//让Alooper线程运行起来
status_t stop();//让Alooer线程停止运行
static int64_t GetNowUs();//获取当前时间
const char *getName() const {//获取当前Alooper的名称
return mName.c_str();
}
protected:
virtual ~ALooper();//虚析构
private:
friend struct AMessage;//友元结构体
struct Event {int64_t mWhenUs;sp<AMessage> mMessage;};//存储Amessage的消息。
Mutex mLock;//锁
Condition mQueueChangedCondition;//条件变量,用于唤醒线程
AString mName;//Alooper的名称
List<Event> mEventQueue;//消息队列,会根据等待时间来从小到大排序
struct LooperThread;//此处是声明。
sp<LooperThread> mThread;//智能指针指向LooperThread
bool mRunningLocally;//线程是否在运行
//使用单独的锁进行回复的处理,因为它总是在另一个线程上。但是,使用中心锁可以避免为每个回复创建mutex
Mutex mRepliesLock;
Condition mRepliesCondition;
//发送一个消息到Aloope中
void post(const sp<AMessage> &msg, int64_t delayUs);
// 创建一个和当前looper一起使用的AReplyToken,AReplyToken主要用于回复消息
sp<AReplyToken> createReplyToken();
//发送方用于等待回复的消息
status_t awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response);
//接收方向发送方回复消息
status_t postReply(const sp<AReplyToken> &replyToken, const sp<AMessage> &msg);
bool loop();//死循环,不断的从消息队列中取出消息。
DISALLOW_EVIL_CONSTRUCTORS(ALooper);
};
2.2 ALooper::GetNowUs
cpp
// static
int64_t ALooper::GetNowUs() {//获取当前时间
return systemTime(SYSTEM_TIME_MONOTONIC)
}
2.3 ALooper::ALooper构造函数
会清除旧的Ahandler
cpp
ALooper::ALooper()
: mRunningLocally(false) {
gLooperRoster.unregisterStaleHandlers();//清除旧的Ahandler。从保存注册Ahandler的列表中删除
}
2.4 析构函数
调用stop函数,让looper线程停止循环,并释放线程资源
cpp
ALooper::~ALooper() {
stop();
}
2.5 ALooper::setName
cpp
void ALooper::setName(const char *name) {//为looper设置名称
mName = name;
}
2.6 ALooper::registerHandler
注册Ahandler并将其保存到一个容器中。
cpp
ALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) {//注册Ahandler,用一个map保存alooper和Ahandler的对应关系
return gLooperRoster.registerHandler(this, handler);
}
cpp
ALooper::handler_id ALooperRoster::registerHandler(const sp<ALooper> &looper, const sp<AHandler> &handler) {
Mutex::Autolock autoLock(mLock);
if (handler->id() != 0) {//此时handler->id()等于0
CHECK(!"A handler must only be registered once.");
return INVALID_OPERATION;
}
HandlerInfo info;
//定义是struct HandlerInfo {
//wp<ALooper> mLooper;
//wp<AHandler> mHandler;
//};
info.mLooper = looper;//赋值looper
info.mHandler = handler;//赋值handler
ALooper::handler_id handlerID = mNextHandlerID++;//mNextHandlerID在构造函数是1,此时handler_id值是1,mNextHandlerID变为2
mHandlers.add(handlerID, info);//保存信息KeyedVector<ALooper::handler_id, HandlerInfo> mHandlers;
handler->setID(handlerID, looper);//此时handlerID等于1,handler持有looper的弱引用
return handlerID;
}
2.7 ALooper::unregisterHandler
取消注册Ahandler,从容器中删除此Ahandler
cpp
void ALooper::unregisterHandler(handler_id handlerID) {//取消注册handler
gLooperRoster.unregisterHandler(handlerID);
}
cpp
void ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
Mutex::Autolock autoLock(mLock);
ssize_t index = mHandlers.indexOfKey(handlerID);//获取handlerID对应的位置
if (index < 0) {
return;
}
const HandlerInfo &info = mHandlers.valueAt(index);
sp<AHandler> handler = info.mHandler.promote();
if (handler != NULL) {//如果handler存在,则设置其id为0
handler->setID(0, NULL);
}
mHandlers.removeItemsAt(index);//移除此handler
}
2.8 ALooper::start
主要作用为:
1.创建了一个LooperThread类对象,此类对象会创建一个线程
2.让线程运行起来。
cpp
//如果runOnCallingThread表示,是否开启新的线程
//如果runOnCallingThread = true:那么当前线程不会再做其它工作,陷入一个死循环。用于循环执行loop()函数。
//如果runOnCallingThread = false:会创建一个子线程,并将loop()逻辑放到这个特定子线程中处理。
status_t start(bool runOnCallingThread = false,bool canCallJava = false,int32_t priority = PRIORITY_DEFAULT);
status_t ALooper::start(bool runOnCallingThread, bool canCallJava, int32_t priority) {//传入的runOnCallingThread=false,canCallJava=false,priority优先级PRIORITY_DEFAULT
if (runOnCallingThread) {//如果不创建新的线程,则当前线程死循环调用loop
{
Mutex::Autolock autoLock(mLock);
if (mThread != NULL || mRunningLocally) {
return INVALID_OPERATION;
}
mrunninglocally = true;//mrunninglocally 为true意味着当前线程陷入loop的死循环
}
do {
} while (loop());
return ok;
}
Mutex::Autolock autoLock(mLock);
if (mThread != NULL || mRunningLocally) {//此时mThread为空
return INVALID_OPERATION;//无效操作
}
mThread = new LooperThread(this, canCallJava);//this是ALooper指针对象,canCallJava是false,new了一个继承自Thread的类
status_t err = mThread->run(mName.empty() ? "ALooper" : mName.c_str(), priority);//让线程跑起来。传递的参数应该是ALooper,priority为PRIORITY_DEFAULT
//线程的threadLoop方法会执行
if (err != OK) {
mThread.clear();
}
return err;
}
此函数的后续流程如下:
2.8.1 LooperThread 构造函数
cpp
struct ALooper::LooperThread : public Thread {
LooperThread(ALooper *looper, bool canCallJava): Thread(canCallJava),mLooper(looper),mThreadId(NULL) {}
//this是ALooper指针对象,canCallJava是false
}
2.8.2 LooperThread构造函数
cpp
struct ALooper::LooperThread : public Thread {
LooperThread(ALooper *looper, bool canCallJava): Thread(canCallJava),mLooper(looper),mThreadId(NULL) {}
//this是ALooper指针对象,canCallJava是false
}
2.8.3 Thread构造函数
cpp
Thread::Thread(bool canCallJava):
mCanCallJava(canCallJava),//canCallJava此时传入的是false
mThread(thread_id_t(-1)),//定义类型是thread_id_t mThread;,代表线程id,
//typedef android_thread_id_t thread_id_t;typedef void* android_thread_id_t;所以android_thread_id_t是一个void*的指针。
mLock("Thread::mLock"),//互斥量
mStatus(OK),
mExitPending(false),
mRunning(false)//表示此线程是否正在运行
#if defined(__ANDROID__)
,
mTid(-1)
#endif
{
}
2.8.4 Thread::run
主要作用为:
1.调用androidCreateRawThreadEtc方法,此方法通过pthread创建了一个线程,并使线程分离,并执行_threadLoop方法
cpp
status_t Thread::run(const char* name, int32_t priority, size_t stack)
//此时传入的参数是name = Alooper,
//stack默认是0,priority为PRIORITY_DEFAULT
{
Mutex::Autolock _l(mLock);
/*
if (mRunning) {//此时为false
// thread already started
return INVALID_OPERATION;//表示线程已经start
}
*/
//重置status和exitPending为其默认值,
mStatus = OK;
mExitPending = false;
mThread = thread_id_t(-1);
//持有自己的强引用
mHoldSelf = this;//定义是sp<Thread> mHoldSelf; this 是当前mThread线程对象
mRunning = true;
bool res;
if (mCanCallJava) {//此时是false
res = createThreadEtc(_threadLoop,this, name, priority, stack, &mThread);
} else {
res = androidCreateRawThreadEtc(_threadLoop,this, name, priority, stack, &mThread);
//此处的作用是通过pthread创建了一个线程,并使线程分离,并执行_threadLoop方法
}
// if (res == false) {//线程创建出错,正常不执行
// mStatus = UNKNOWN_ERROR; // something happened!
// mRunning = false;
// mThread = thread_id_t(-1);
// mHoldSelf.clear(); // "this" may have gone away after this.
// return UNKNOWN_ERROR;
// }
return OK;
}
2.8.5 androidCreateRawThreadEtc
主要作用为:
1.通过pthread_create创建一个分离的线程,并执行_threadLoop方法
cpp
int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
void *userData,
const char* threadName __android_unused,
int32_t threadPriority,
size_t threadStackSize,
android_thread_id_t *threadId)
//entryFunction是_threadLoop函数,android_thread_func_t是一个函数指针
//定义是typedef int (*android_thread_func_t)(void*);
//userData是Thread的类的指针的对象
//__android_unused是Alooper
//threadPriority为PRIORITY_DEFAULT
//threadStackSize是0
//threadId = -1
{
pthread_attr_t attr;//创建线程属性变量
pthread_attr_init(&attr);//初始化线程属性
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);设置线程属性是否分离。PTHREAD_CREATE_DETACHED为分离
#if defined(__ANDROID__) /* valgrind is rejecting RT-priority create reqs */
/*
if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {//如果线程不是默认优先级
// Now that the pthread_t has a method to find the associated
// android_thread_id_t (pid) from pthread_t, it would be possible to avoid
// this trampoline in some cases as the parent could set the properties
// for the child. However, there would be a race condition because the
// child becomes ready immediately, and it doesn't work for the name.
// prctl(PR_SET_NAME) only works for self; prctl(PR_SET_THREAD_NAME) was
// proposed but not yet accepted.
thread_data_t* t = new thread_data_t;
t->priority = threadPriority;
t->threadName = threadName ? strdup(threadName) : NULL;
t->entryFunction = entryFunction;
t->userData = userData;
entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
userData = t;
}*/
#endif
// if (threadStackSize) {//此时是0,不设置
// pthread_attr_setstacksize(&attr, threadStackSize);//设置线程属性中线程栈的大小
// }
errno = 0;
pthread_t thread;
int result = pthread_create(&thread, &attr,(android_pthread_entry)entryFunction, userData);//attr是线程属性。
//entryFunction是线程要执行的函数_threadLoop,userData是Thread的强引用对象
pthread_attr_destroy(&attr);//创建线程完成后,可以销毁属性。
if (result != 0) {
ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, %s)\n"
"(android threadPriority=%d)",
entryFunction, result, strerror(errno), threadPriority);
return 0;
}
// Note that *threadID is directly available to the parent only, as it is
// assigned after the child starts. Use memory barrier / lock if the child
// or other threads also need access.
if (threadId != nullptr) {
*threadId = (android_thread_id_t)thread; // XXX: this is not portable
}
return 1;
}
2.8.6 _threadLoop
主要作用为:
1.死循环调用继承类的threadLoop方法,当threadLoop方法返回true并且没有调用requsetexit函数时,会一直循环的调用threadLoop函数
cpp
int Thread::_threadLoop(void* user)//此处传入的是Thread强引用对象
{
Thread* const self = static_cast<Thread*>(user);//将void*类的指针转化为Thread*
sp<Thread> strong(self->mHoldSelf);//获取Thread的强引用,此处是self->mHoldSelf是sp类型,故此处是拷贝构造,指向的对象引用会是2
wp<Thread> weak(strong);//获取弱引用
self->mHoldSelf.clear();//让强引用减一
#if defined(__ANDROID__)
// this is very useful for debugging with gdb
self->mTid = gettid();
#endif
bool first = true;
do {
bool result;
if (first) {//如果是第一次运行线程。
first = false;
self->mStatus = self->readyToRun();//此处就是返回一个ok
result = (self->mStatus == OK);
if (result && !self->exitPending()) {
result = self->threadLoop();//此处函数是虚函数,需要类去继承。调用的是子类的threadLooper函数。
//在此处是struct ALooper::LooperThread : public Thread类的threadLoop方法
}
} else {
result = self->threadLoop();//此处函数是虚函数,需要类去继承。调用的是子类的threadLooper函数。
//在此处是struct ALooper::LooperThread : public Thread类的threadLoop方法
}
// establish a scope for mLock
{
Mutex::Autolock _l(self->mLock);
if (result == false || self->mExitPending) {//一般result都是true,self->mExitPending默认是false,
//表示是否退出,在requestExit函数和requestExitAndWait函数中会设置为true
self->mExitPending = true;
self->mRunning = false;
// clear thread ID so that requestExitAndWait() does not exit if
// called by a new thread using the same thread ID as this one.
//清除线程ID
self->mThread = thread_id_t(-1);
// note that interested observers blocked in requestExitAndWait are
// awoken by broadcast, but blocked on mLock until break exits scope
self->mThreadExitedCondition.broadcast();//mThreadExitedCondition是Condition类对象。
//底层调用了pthread_cond_broadcast,唤醒所有在此conditon等待的线程
break;
}
}
// Release our strong reference, to let a chance to the thread
// to die a peaceful death.
strong.clear();//短暂的让强指针引用-1,以便有机会让线程释放。
// And immediately, re-acquire a strong reference for the next loop
strong = weak.promote();//立即获取强引用
} while(strong != nullptr);//死循环
return 0;
}
2.8.7 LooperThread::threadLoop
cpp
//线程调用run方法后,会调用threadLoop方法,当其返回true并且没有调用requsetexit函数时,会一直循环的调用threadLoop函数
struct ALooper::LooperThread : public Thread {
virtual bool threadLoop() {return mLooper->loop();}
}
2.8.8 ALooper::loop
此函数后续仍会遇见,我们现在只介绍当前的作用。
此时,looper刚启动,所以其消息队列中的消息为空,故此时是线程在条件变量上进行了等待。
当另外一个线程生成AMessage消息,并post时,会将此消息post到消息队列中,然后唤醒此looper线程,此时消息队列存在消息,会取出消息,并执行deliver函数去运输消息,最后会执行此消息。
cpp
bool ALooper::loop() {
Event event;//event结构体为
//struct Event {
//int64_t mWhenUs;
//sp<AMessage> mMessage;
//};
{
Mutex::Autolock autoLock(mLock);
if (mThread == NULL && !mRunningLocally) {//此时mThread不为空,mRunningLocally值为flase
return false;
}
if (mEventQueue.empty()) {//此时消息队列应该是空的
mQueueChangedCondition.wait(mLock);//此处定义是Condition mQueueChangedCondition;此线程阻塞在这里等待。
//调用的是inline status_t Condition::wait(Mutex& mutex) {return -pthread_cond_wait(&mCond, &mutex.mMutex);}
return true;
//后面暂时不执行
// }
// int64_t whenUs = (*mEventQueue.begin()).mWhenUs;
// int64_t nowUs = GetNowUs();
// if (whenUs > nowUs) {
// int64_t delayUs = whenUs - nowUs;
// if (delayUs > INT64_MAX / 1000) {
// delayUs = INT64_MAX / 1000;
// }
// mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll);
// return true;
// }
// event = *mEventQueue.begin();
// mEventQueue.erase(mEventQueue.begin());
// }
// event.mMessage->deliver();
// // NOTE: It's important to note that at this point our "ALooper" object
// // may no longer exist (its final reference may have gone away while
// // delivering the message). We have made sure, however, that loop()
// // won't be called again.
// return true;
}
}
}
2.9 ALooper::stop
此函数内部主要会调用调用requestExit方法。此方法会将一个线程循环的flag标志设置为true,等到下一次线程循环的时候,线程便会退出循环,然后释放线程资源。
cpp
status_t ALooper::stop() {
sp<LooperThread> thread;
bool runningLocally;
{
Mutex::Autolock autoLock(mLock);
thread = mThread;//拷贝构造,使得强引用计数+1了
runningLocally = mRunningLocally;
mThread.clear();//强引用计数减1
mRunningLocally = false;
}
if (thread == NULL && !runningLocally) {
return INVALID_OPERATION;
}
if (thread != NULL) {//停止线程
thread->requestExit();//调用requestExit方法。查看Thread类的结构可知,mExitPending = true会设置为true
}
.
mQueueChangedCondition.signal();//通知信号量等待的线程。然后会结束死循环。线程分离会自动销毁。
{
Mutex::Autolock autoLock(mRepliesLock);
mRepliesCondition.broadcast();//广播唤醒在mRepliesCondition等待的所有线程
}
if (!runningLocally && !thread->isCurrentThread()) {
// If not running locally and this thread _is_ the looper thread,
// the loop() function will return and never be called again.
//如果不是在本地运行,并且此线程_is_为looper线程,则loop()函数将返回并且不再被调用。
thread->requestExitAndWait();
}
return OK;
}
此函数的后续流程为:
2.9.1 Thread::requestExit
设置mExitPending的标志位为true,线程就会退出循环,然后释放线程资源
cpp
//requestExit() 请求退出线程,立即返回。
void Thread::requestExit()
{
Mutex::Autolock _l(mLock);
mExitPending = true;//设置mExitPending的值为true,此时_threadLoop会执行下面的代码块。然后退出循环。然后由于线程是分离的,_threadLoop函数执行完,会自动回收。
}
2.9.2 Thread::requestExitAndWait
当我们调用stop的时候是在A线程中,当我们设置mExitPending为ture后,表示要释放之前创建的分离的looper线程,而此时A线程需要等待looper线程释放完相关资源后,再往下走。
cpp
status_t Thread::requestExitAndWait()
{
Mutex::Autolock _l(mLock);
if (mThread == getThreadId()) {//如果是之前使用当前线程作为处理消息的线程,而不是新创建了一个线程。
//那么此时自己调用requestExitAndWait,需要返回,不需要在下面mThreadExitedCondition条件变量上进行等待,因为只有一个线程,
//此时线程会一直等待,因为没有其他线程唤醒。
ALOGW(
"Thread (this=%p): don't call waitForExit() from this "
"Thread object's thread. It's a guaranteed deadlock!",
this);
return WOULD_BLOCK;
}
mExitPending = true;
while (mRunning == true) {
mThreadExitedCondition.wait(mLock);
}
// This next line is probably not needed any more, but is being left for
// historical reference. Note that each interested party will clear flag.
mExitPending = false;
return mStatus;
}
2.9.3 _threadLoop
此时我们需要回到looper线程的这个函数,此时self->mExitPending为ture,然后当前线程会退出死循环,清除线程的id,同时唤醒之前等待的A线程。由于是分离的线程,故此时分离的线程会自动释放资源。
cpp
int Thread::_threadLoop(void* user)//此处传入的是Thread强引用对象
{
Thread* const self = static_cast<Thread*>(user);//将void*类的指针转化为Thread*
sp<Thread> strong(self->mHoldSelf);//获取Thread的强引用,此处是self->mHoldSelf是sp类型,故此处是拷贝构造,指向的对象引用会是2
wp<Thread> weak(strong);//获取弱引用
self->mHoldSelf.clear();//让强引用减一
#if defined(__ANDROID__)
// this is very useful for debugging with gdb
self->mTid = gettid();
#endif
bool first = true;
do {
bool result;
if (first) {//如果是第一次运行线程。
first = false;
self->mStatus = self->readyToRun();//此处就是返回一个ok
result = (self->mStatus == OK);
if (result && !self->exitPending()) {
result = self->threadLoop();//此处函数是虚函数,需要类去继承。调用的是子类的threadLooper函数。
//在此处是struct ALooper::LooperThread : public Thread类的threadLoop方法
}
} else {
result = self->threadLoop();//此处函数是虚函数,需要类去继承。调用的是子类的threadLooper函数。
//在此处是struct ALooper::LooperThread : public Thread类的threadLoop方法
}
// establish a scope for mLock
{
Mutex::Autolock _l(self->mLock);
if (result == false || self->mExitPending) {//一般result都是true,self->mExitPending默认是false,
//表示是否退出,在requestExit函数和requestExitAndWait函数中会设置为true
self->mExitPending = true;
self->mRunning = false;
// clear thread ID so that requestExitAndWait() does not exit if
// called by a new thread using the same thread ID as this one.
//清除线程ID
self->mThread = thread_id_t(-1);
// note that interested observers blocked in requestExitAndWait are
// awoken by broadcast, but blocked on mLock until break exits scope
self->mThreadExitedCondition.broadcast();//mThreadExitedCondition是Condition类对象。
//底层调用了pthread_cond_broadcast,唤醒所有在此conditon等待的线程
break;
}
}
// Release our strong reference, to let a chance to the thread
// to die a peaceful death.
strong.clear();//短暂的让强指针引用-1,以便有机会让线程释放。
// And immediately, re-acquire a strong reference for the next loop
strong = weak.promote();//立即获取强引用
} while(strong != nullptr);//死循环
return 0;
}
2.10 ALooper::post
主要作用为:
1.将消息根据时延大小放到消息队列的指定位置,然后唤醒Alooper线程。
cpp
void ALooper::post(const sp<AMessage> &msg, int64_t delayUs) {
Mutex::Autolock autoLock(mLock);
int64_t whenUs;
if (delayUs > 0) {//表示是否延时发送
int64_t nowUs = GetNowUs();
whenUs = (delayUs > INT64_MAX - nowUs ? INT64_MAX : nowUs + delayUs);
} else {
whenUs = GetNowUs();//不延时,获取当前时间
}
List<Event>::iterator it = mEventQueue.begin();//此处是遍历消息队列
while (it != mEventQueue.end() && (*it).mWhenUs <= whenUs) {//遍历消息队列,按照时延从小到大排序,找到当前消息应该插入的位置。
++it;
}
Event event;
event.mWhenUs = whenUs;
event.mMessage = msg;//生成event
if (it == mEventQueue.begin()) {//如果当前消息应该插入到消息队列的队首
mQueueChangedCondition.signal();//则使用条件遍历唤醒线程
}
mEventQueue.insert(it, event);//插入该event到指定位置
}
2.11 ALooper::loop
主要作用为:
1.从消息队列中取出消息,然后将消息发送到指定的Ahandler处理者去处理此消息。
cpp
bool ALooper::loop() {
Event event;
{
Mutex::Autolock autoLock(mLock);
if (mThread == NULL && !mRunningLocally) {
return false;
}
if (mEventQueue.empty()) {//此时不为空,不执行
mQueueChangedCondition.wait(mLock);
return true;
}
int64_t whenUs = (*mEventQueue.begin()).mWhenUs;//获取消息队列的位于头部的event的时延,因为位于头部的event是时延最小的消息
int64_t nowUs = GetNowUs();
if (whenUs > nowUs) {//如果时延大于当前时间,意味着时间还没到。
int64_t delayUs = whenUs - nowUs;
if (delayUs > INT64_MAX / 1000) {
delayUs = INT64_MAX / 1000;
}
mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll);//因为位于头部的event是时延最小的消息,所以此时需要等待时间到达,时间到达后,返回true,然后开启下一次循环
return true;
}
event = *mEventQueue.begin();//取出头部的event事件
mEventQueue.erase(mEventQueue.begin());//将此evnet从消息队列中删除
}
event.mMessage->deliver();//调用Amessage的deliver方法
// NOTE: It's important to note that at this point our "ALooper" object
// may no longer exist (its final reference may have gone away while
// delivering the message). We have made sure, however, that loop()
// won't be called again.
return true;
}
2.12 ALooper::createReplyToken
主要作用为:
1.创建一个AReplyToken对象,用于表示是哪个消息需要回复。
cpp
sp<AReplyToken> ALooper::createReplyToken() {//此时A线程发送消息,然后阻塞等待B线程发送回复消息。
//然后b线程收到消息后,发送消息到A线程。在这个流程中,AReplyToken在A线程的发送消息的时候被创建,然后保存该回复令牌到发送消息内部。
//当发送的消息到达B线程后,b线程会取出此回复令牌,然后将回复的消息,设置进此AReplyToken对象中,由于A线程也持有此对象,故A线程会死循环的拿回复的消息。
return new AReplyToken(this);
}
2.13 ALooper::awaitResponse
死循环取回回复,到response中。取回后返回ok,未取回,则一直wait等待阻塞。
cpp
status_t ALooper::awaitResponse(const sp<AReplyToken> &replyToken, sp<AMessage> *response) {
// return status in case we want to handle an interrupted wait
Mutex::Autolock autoLock(mRepliesLock);
CHECK(replyToken != NULL);
while (!replyToken->retrieveReply(response)) {//死循环取回回复,到response中。取回后返回ok,未取回,则一直wait等待阻塞。
{
Mutex::Autolock autoLock(mLock);
if (mThread == NULL) {
return -ENOENT;
}
}
mRepliesCondition.wait(mRepliesLock);
}
return OK;
}
2.14 ALooper::postReply
1.将接收方Ahandler回复的Amessage设置到replyToken对象中。
2.唤醒发送方wait之前wait阻塞的地方。
cpp
status_t ALooper::postReply(const sp<AReplyToken> &replyToken, const sp<AMessage> &reply) {
Mutex::Autolock autoLock(mRepliesLock);
status_t err = replyToken->setReply(reply);//将此回复消息reply设置到replyToken中
if (err == OK) {
mRepliesCondition.broadcast();//广播之前mRepliesCondition.wait(mRepliesLock)的地方。
}
return err;
}
将Amessage消息保存到AReplyToken类对象中。
cpp
status_t AReplyToken::setReply(const sp<AMessage> &reply) {
if (mReplied) {
ALOGE("trying to post a duplicate reply");
return -EBUSY;
}
CHECK(mReply == NULL);
mReply = reply;//将传入的Amessage消息保存到AReplyToken中
mReplied = true;
return OK;
}