当前位置: 首页 > article >正文

【android12】【AHandler】【1.AHandler异步无回复消息原理篇】

系列文章目录

 可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm=1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm=1001.2014.3001.5501


1.简介

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

 

 1.2 类图

2.使用步骤

2.1 流程介绍

第一步:创建TestHandler类继承自AHandler,并重写方法onMessageReceived

class TestHandler: public AHandler {
public:
   enum {//此枚举类型用于new message时传入
            kWhat_Delete,   
   };

   TestHandler(){}
		
        virtual void onMessageReceived(const sp<AMessage>& msg);
        wp<DataManager> mwpDataManagerPtr;
};



void TestHandler::onMessageReceived(const sp<AMessage>& msg) {
    switch (msg->what()) {
        case kWhat_Delete:
            dodelete(msg);
    }
}


void TestHandler::dodelete(const sp<AMessage>& msg) {
    AString accountName;
    msg->findString("accountName", &accountName));//accountName对应的值,会写入accountName对象中
}

 第二步: new 一个Alooper

sp<ALooper> mTestLooper = new ALooper()

 第三步:new一个继承自AHandler的TestHandler类的mTestHandler对象

sp<TestHandler> mTestHandler = new TestHandler() 

第四步:启动looper线程。

mTestLooper ->start()

 第五步:注册handler到looper中。

ALooper::handler_id mHandlerID = mTestLooper->registerHandler(mTestHandler);

 第六步:new AMessage并发送给handler

sp<AMessage> msg = new AMessage(TestHandler::kWhat_Delete, mTestHandler);
   msg->setString("Name", "zc");
   msg->post();

 第七步:使用并处理消息

void TestHandler::onMessageReceived(const sp<AMessage>& msg) {
    switch (msg->what()) {
        case kWhat_Delete:
            dodelete(msg);
    }
}


void TestHandler::dodelete(const sp<AMessage>& msg) {
    AString accountName;
    msg->findString("accountName", &accountName));//accountName对应的值,会写入accountName对象中
}

 第八步:注销handler

mTestLooper->unregisterHandler(mHandlerID);

 第九步:停止looper,并置空

mTestLooper->stop();
mTestLooper= nullptr;

 第十步:置空handler

mTestHandler = nullptr;

3.源码分析

追随源码的过程较为复杂,因此先奉上相关时序图。

 (可保存到本地放大观看)

3.1 第一步分析

创建TestHandler类,此类继承自AHandler,需要重写方法onMessageReceived方法,当Alooper中存在有消息的时候,此方法会被调用。

3.2 第二步分析

  第二步: new 一个Alooper

sp<ALooper> mTestLooper = new ALooper()

new 了一个Alooper,查看其构造函数。

3.2.1 Alooper构造函数

ALooper::ALooper(): mRunningLocally(false) {//mRunningLocally表示是否loop在运行
    //清理陈旧的AHandler
    gLooperRoster.unregisterStaleHandlers();//gLooperRoster定义是ALooperRoster,查看其结构,
	//主要作用是用于注册取消注册handler,保存handler和looper的对应关系。
}

当ALooper被构造出来的时候,其自身的成员变量condtion也被构造出来了。所以我们仍需要看看

Condition中做了什么

3.2.2 Condition构造函数

主要是构造了一些后续创建pthread需要的一些变量信息,用于后续创建新的线程。

inline Condition::Condition() : Condition(PRIVATE) {//默认构造
}






inline Condition::Condition(int type) {//type是PRIVATE
    pthread_condattr_t attr;//条件变量属性
    pthread_condattr_init(&attr);//条件属性初始化
#if defined(__linux__)
    pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);//采用相对时间等待,可以避免因系统调整时间,导致等待时间出现错误。
#endif
    /*
    if (type == SHARED) {//设置是否可以被其他进程使用。此处是私有
        pthread_condattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
    }
    */

    pthread_cond_init(&mCond, &attr);//初始化条件变量
    pthread_condattr_destroy(&attr);//销毁条件变量属性

}

3.2.3 unregisterStaleHandlers

此函数用于清楚一些旧的已经没有使用的Handlers

void ALooperRoster::unregisterStaleHandlers() {

    Vector<sp<ALooper> > activeLoopers;
    {
        Mutex::Autolock autoLock(mLock);

        for (size_t i = mHandlers.size(); i > 0;) {//mHandlers定义是KeyedVector<ALooper::handler_id, HandlerInfo> 
		//mHandlers;HandlerInfo中保存了handler和looper。

            i--;
            const HandlerInfo &info = mHandlers.valueAt(i);

            sp<ALooper> looper = info.mLooper.promote();
            if (looper == NULL) {//循环取出looper,如果looper为空,代表此looper已经被智能指针析构,则移除保存的注册信息
                ALOGV("Unregistering stale handler %d", mHandlers.keyAt(i));
                mHandlers.removeItemsAt(i);
            } else {//如果looper不为空,则添加looper到activeLoopers中
                activeLoopers.add(looper);
            }
        }
    }
}

3.3 第三步分析

 第三步:new一个继承自AHandler的TestHandler类的mTestHandler对象

sp<TestHandler> mTestHandler = new TestHandler() 

new一个继承自AHandler的TestHandler类的mTestHandler对象,查看其构造函数

TestHandler(){}





struct AHandler : public RefBase {
    AHandler()
        : mID(0),//定义是ALooper::handler_id mID;
          mVerboseStats(false),
          mMessageCounter(0) {//消息的数量
    }

3.4 第四步分析

启动Alooper线程

3.4.1 start

主要作用为:

1.创建了一个LooperThread类对象,此类对象会创建一个线程

2.让线程运行起来。

/第四步
//如果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) {
        // {
            // 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;
}

3.4.2 LooperThread构造函数

struct ALooper::LooperThread : public Thread {
    LooperThread(ALooper *looper, bool canCallJava): Thread(canCallJava),mLooper(looper),mThreadId(NULL) {}
//this是ALooper指针对象,canCallJava是false
}

3.4.3 Thread构造函数

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
{
}

3.4.4 Thread::run

主要作用为:

1.调用androidCreateRawThreadEtc方法,此方法通过pthread创建了一个线程,并使线程分离,并执行_threadLoop方法

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;
}

3.4.5 androidCreateRawThreadEtc

主要作用为:

1.通过pthread_create创建一个分离的线程,并执行_threadLoop方法

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;
}

3.4.6 _threadLoop

主要作用为:

1.死循环调用继承类的threadLoop方法,当threadLoop方法返回true并且没有调用requsetexit函数时,会一直循环的调用threadLoop函数

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;
}

3.4.7 LooperThread::threadLoop

//线程调用run方法后,会调用threadLoop方法,当其返回true并且没有调用requsetexit函数时,会一直循环的调用threadLoop函数
struct ALooper::LooperThread : public Thread {
virtual bool threadLoop() {return mLooper->loop();}
}

3.4.8 ALooper::loop

此函数后续仍会遇见,我们现在只介绍当前的作用。

此时,looper刚启动,所以其消息队列中的消息为空,故此时是线程在条件变量上进行了等待。

当另外一个线程生成AMessage消息,并post时,会将此消息post到消息队列中,然后唤醒此looper线程,此时消息队列存在消息,会取出消息,并执行deliver函数去运输消息,最后会执行此消息。

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;
}
}
}

3.5 第五步分析

注册handler到looper中。

ALooper::handler_id mHandlerID = mTestLooper->registerHandler(mTestHandler);
ALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) {
    return gLooperRoster.registerHandler(this, handler);//此处this是mTestLooper,handler是mTestHandler
}

 将looper和handler保存起来,并添加到一个容器中

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;
}






inline void setID(ALooper::handler_id id, const wp<ALooper> &looper) {
    mID = id;
    mLooper = looper;
}

3.6 第六步分析

 第六步:new AMessage并发送给handler

sp<AMessage> msg = new AMessage(TestHandler::kWhat_Delete, mTestHandler);
   msg->setString("Name", "zc");
   msg->post();

3.6.1 AMessage的构造函数

AMessage(uint32_t what, const sp<const AHandler> &handler);
AMessage::AMessage(uint32_t what, const sp<const AHandler> &handler)//handler代表要处理此消息的handler
    : mWhat(what) {//定义为uint32_t mWhat;
    setTarget(handler);
}

3.6.2 AMessage::setTarget

找到handler对应的id,handler对象和looper对象

void AMessage::setTarget(const sp<const AHandler> &handler) {
    if (handler == NULL) {
        mTarget = 0;
        mHandler.clear();
        mLooper.clear();
    } else {
        mTarget = handler->id();//定义为ALooper::handler_id mTarget;
        mHandler = handler->getHandler();//定义为wp<AHandler> mHandler;//拿到的是handler的弱引用
        mLooper = handler->getLooper();//定义为wp<ALooper> mLooper;//拿到的是mLooper的弱引用
    }
}

3.6.3 setString

void AMessage::setString(const char *name, const AString &s) {
    setString(name, s.c_str(), s.size());
}


void AMessage::setString(const char *name, const char *s, ssize_t len) {//此时name是Name,s应该是zc,len是zc的长度
    Item *item = allocateItem(name);//如果此name对应的item存在,则删除此item的value值。如果不存在,
	//则分配一个item。并放入vector中存储起来
	//此处相当于name是key,而zc是对应的value的值
    if (item) {
        item->mType = kTypeString;//设置数据类型为string
        item->u.stringValue = new AString(s, len < 0 ? strlen(s) : len);//用AString保存字符串
    }
}

3.6.4 AMessage::allocateItem

分配一个Item对象,用于保存string信息

AMessage::Item *AMessage::allocateItem(const char *name) {
    size_t len = strlen(name);
    size_t i = findItemIndex(name, len);//查找是否已经存在
    Item *item;

    if (i < mItems.size()) {//如果返回的i是小于存储Item的容器大小,则表示此name对应的item已存在
        item = &mItems[i];
        freeItemValue(item);//删除此name对应的item的value值
    } else {//否则就是此name对应的item不存在
        CHECK(mItems.size() < kMaxNumItems);
        i = mItems.size();
        // place a 'blank' item at the end - this is of type kTypeInt32
        mItems.emplace_back(name, len);//将此item放入vector的末尾端,默认type是kTypeInt32
        item = &mItems[i];
    }

    return item;
}
inline size_t AMessage::findItemIndex(const char *name, size_t len) const {
#ifdef DUMP_STATS
    size_t memchecks = 0;
#endif
    size_t i = 0;
    for (; i < mItems.size(); i++) {//mItem的定义是std::vector<Item> mItems;遍历所有的Item
        if (len != mItems[i].mNameLength) {//如果name的长度不同,则说明不是此item
            continue;
        }
		
        if (!memcmp(mItems[i].mName, name, len)) {//如果name的长度相同,则比较name,如果name完全相等,
		//则表示此item已经存在,退出循环,如果不相同,则继续循环
            break;
        }
    }
#endif
    return i;//返回在vector的位置
}

 如果存在,则会删除name对应的value值

//删除此name对应的item的value值
void AMessage::freeItemValue(Item *item) {
    switch (item->mType) {
        case kTypeString:
        {
            delete item->u.stringValue;
            break;
        }

        case kTypeObject:
        case kTypeMessage:
        case kTypeBuffer:
        {
            if (item->u.refValue != NULL) {
                item->u.refValue->decStrong(this);
            }
            break;
        }

        default:
            break;
    }
    item->mType = kTypeInt32; // clear type

 Item结构体如下

struct Item {
        union {
            int32_t int32Value;
            int64_t int64Value;
            size_t sizeValue;
            float floatValue;
            double doubleValue;
            void *ptrValue;
            RefBase *refValue;
            AString *stringValue;
            Rect rectValue;
        } u;
        const char *mName;//保存mName,在这里是Name
        size_t      mNameLength;//此时是Name的长度
        Type mType;
		//定义是    
		//enum Type {
        //kTypeInt32,
        //kTypeInt64,
        //kTypeSize,
        //kTypeFloat,
        //kTypeDouble,
        //kTypePointer,
        //kTypeString,
        //kTypeObject,
        //kTypeMessage,
        //kTypeRect,
        //kTypeBuffer,
		//};
        void setName(const char *name, size_t len);
        Item() : mName(nullptr), mNameLength(0), mType(kTypeInt32) { }
        Item(const char *name, size_t length);
};

3.6.5 AMessage::post

然后我们继续看post消息,此处会调用调用looper的post方法,将消息插入到消息队列中,然后再唤醒

status_t AMessage::post(int64_t delayUs) {//m默认delayUs=0
    sp<ALooper> looper = mLooper.promote();//转化此为强指针,因为AMessage在构造的时候会传递Ahandler,
	//而Ahandler存在looper的弱引用,是在looper注册registerHandler时,赋值给Ahandler
    if (looper == NULL) {
        ALOGW("failed to post message as target looper for handler %d is gone.", mTarget);
        return -ENOENT;
    }

    looper->post(this, delayUs);//调用looper的post方法,this是此AMessage对象
    return OK;
}

3.6.6 ALooper::post

遍历消息队列,按照时延从小到大排序,找到当前消息应该插入的位置。然后使用条件变量唤醒之前等待的looper线程。

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到指定位置
}

3.6.7 ALooper::loop

 此处是3.4.8  looper在无消息的时候阻塞在mQueueChangedCondition.wait的地方,此时被唤醒后

 会从消息队列中取出对应的消息,然后判断消息的时延,如果大于当前时间,则会继续等待,然后,从消息队列中取出对应的Amessage消息,并调用mMessage->deliver方法。此方法会将消息进一步传递给对应的Ahandler进行处理。

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方法
    return true;
}

 3.6.8 Condition::waitRelative

主要作用为:

1.如果消息需要多少秒后再处理,则此时线程在条件变量上等待传入的时间。

inline status_t Condition::waitRelative(Mutex& mutex, nsecs_t reltime) {//传入的reltime是纳秒为单位
    struct timespec ts;
#if defined(__linux__)
    clock_gettime(CLOCK_MONOTONIC, &ts);//获取系统时间,并赋值给ts
#else // __APPLE__
    // // Apple doesn't support POSIX clocks.
    // struct timeval t;
    // gettimeofday(&t, nullptr);
    // ts.tv_sec = t.tv_sec;
    // ts.tv_nsec = t.tv_usec*1000;
#endif

    // On 32-bit devices, tv_sec is 32-bit, but `reltime` is 64-bit.
    int64_t reltime_sec = reltime/1000000000;

    ts.tv_nsec += static_cast<long>(reltime%1000000000);//处理时间
    if (reltime_sec < INT64_MAX && ts.tv_nsec >= 1000000000) {
        ts.tv_nsec -= 1000000000;
        ++reltime_sec;
    }

    int64_t time_sec = ts.tv_sec;
    if (time_sec > INT64_MAX - reltime_sec) {
        time_sec = INT64_MAX;
    } else {
        time_sec += reltime_sec;
    }

    ts.tv_sec = (time_sec > LONG_MAX) ? LONG_MAX : static_cast<long>(time_sec);

    return -pthread_cond_timedwait(&mCond, &mutex.mMutex, &ts);//等待条件变量。如果超时会自动执行下一句
}

3.6.9 AMessage::deliver

调用处理者handler的deliverMessage函数

void AMessage::deliver() {
    sp<AHandler> handler = mHandler.promote();//升级为handler的强引用
    if (handler == NULL) {
        ALOGW("failed to deliver message as target handler %d is gone.", mTarget);
        return;
    }
    handler->deliverMessage(this);//此时this是AMessage对象
}

3.6.10 AHandler::deliverMessage

此时我们便会回到第一步我们继承自Ahandler的子类——TestHandler类的onMessageReceived方法。

至此,异步的消息处理过程我们已经完毕了。

void AHandler::deliverMessage(const sp<AMessage> &msg) {
    onMessageReceived(msg);//此时便回到了继承Ahndler的CommonActionHandler中
    mMessageCounter++;//message数量+1

    if (mVerboseStats) {//默认mVerboseStats值为false,代表详细状态,主要用于dump信息时会用到
        uint32_t what = msg->what();
        ssize_t idx = mMessages.indexOfKey(what);
        if (idx < 0) {
            mMessages.add(what, 1);
        } else {
            mMessages.editValueAt(idx)++;
        }
    }
}

 3.7 第七步分析

第六步末尾我们已经知道此时便走到了我们自己创建的类去处理和消费消息了。

void TestHandler::onMessageReceived(const sp<AMessage>& msg) {
    switch (msg->what()) {
        case kWhat_Delete:
            dodelete(msg);
    }
}


void TestHandler::dodelete(const sp<AMessage>& msg) {
    AString accountName;
    msg->findString("accountName", &accountName));//accountName对应的值,会写入accountName对象中
}

 3.8 第八步分析

 第八步:注销handler

mTestLooper->unregisterHandler(mHandlerID);
void ALooper::unregisterHandler(handler_id handlerID) {//取消注册的handler
    gLooperRoster.unregisterHandler(handlerID);
}

3.8.1 unregisterHandler

我们在注册的时候,会将handler和looper放在mHandlers容器中,而取消注册的时候便是将其从此容器中删除。

void ALooperRoster::unregisterHandler(ALooper::handler_id handlerID) {
    Mutex::Autolock autoLock(mLock);

    ssize_t index = mHandlers.indexOfKey(handlerID);//从保存HandlerInfo的容器中找出对应的HandlerInfo

    if (index < 0) {
        return;
    }

    const HandlerInfo &info = mHandlers.valueAt(index);

    sp<AHandler> handler = info.mHandler.promote();

    if (handler != NULL) {
        handler->setID(0, NULL);//如果handler存在,则设置其id为0
    }

    mHandlers.removeItemsAt(index);//从容器中删除此HandlerInfo
}

3.9 第九步分析

停止looper,并置空

mTestLooper->stop();
mTestLooper= nullptr;

 3.9.1 stop

此函数内部主要会调用调用requestExit方法。此方法会将一个线程循环的flag标志设置为true,等到下一次线程循环的时候,线程便会退出循环,然后释放线程资源。

status_t ALooper::stop() {
    sp<LooperThread> thread;
    bool runningLocally;

    {
        Mutex::Autolock autoLock(mLock);

        thread = mThread;//拷贝构造,使得强引用计数+1了
        runningLocally = mRunningLocally;//值为false
        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()) {
		//如果不是在本地运行,并且此线程_is_为looper线程,则loop()函数将返回并且不再被调用。
        thread->requestExitAndWait();
    }
    return OK;
}

3.9.2 Thread::requestExit

设置mExitPending的标志位为true,线程就会退出循环,然后释放线程资源

//requestExit() 请求退出线程,立即返回。
void Thread::requestExit()
{
    Mutex::Autolock _l(mLock);
    mExitPending = true;//设置mExitPending的值为true,此时_threadLoop会执行下面的代码块。然后退出循环。然后由于线程是分离的,_threadLoop函数执行完,会自动回收。
}

 3.9.3 Thread::requestExitAndWait

当我们调用stop的时候是在A线程中,当我们设置mExitPending为ture后,表示要释放之前创建的分离的B线程,而此时A线程需要等待B线程释放完相关资源后,再往下走。

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;
}

3.9.4 _threadLoop

此时我们需要回到B线程的这个函数,此时self->mExitPending为ture,然后当前线程会退出死循环,清除线程的id,同时唤醒之前等待的A线程。由于是分离的线程,故此时分离的线程会自动释放资源。

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;
}


http://www.kler.cn/a/377749.html

相关文章:

  • 嵌入式科普(25)Home Assistant米家集成意味着IOT的核心是智能设备
  • 商品线上个性定制,并实时预览3D定制效果,是如何实现的?
  • RK3506开发板:智能硬件领域的新选择,带来卓越性能与低功耗
  • HTML-CSS(day01)
  • Python知识图谱框架
  • Django 模型中使用选择(choices):全面指南
  • 整合 flatten-maven-plugin 插件:解决子模块单独打包失败问题
  • 字符串左旋 (干货无废话)
  • flutter-防抖
  • 如何使用AdsPower指纹浏览器克服爬虫技术限制,安全高效进行爬虫!
  • 阿里国际2025届校园招聘 0826算法岗笔试
  • 【JavaEE初阶】深入理解TCP协议特性之延时应答,捎带应答,面向字节流以及异常处理
  • 修改 Docker 镜像默认存储位置的方法
  • 申请CNAS软件测试资质,如何选择测试工具最具性价比?
  • 三、Kafka集群
  • Vue常用的修饰符有哪些?
  • 基于PyTorch的大语言模型微调指南:Torchtune完整教程与代码示例
  • MATLAB FDATool工具箱入门教程
  • ubuntu20.04 加固方案-设置用户缺省UMASK
  • Vue 学习随笔系列十三 -- ElementUI 表格合并单元格
  • redis详细教程(5.AOP和RDB持久化)
  • 在 ubuntu20.04 安装 docker
  • 无人机拦截捕获/直接摧毁算法详解!
  • Dockerfile 增强新语法
  • A Consistent Dual-MRC Framework for Emotion-cause Pair Extraction——论文阅读笔记
  • 【JAVA】利用钉钉自定义机器人监控NACOS服务,实现实时下线通知