3 Alooper分析

来源:互联网 发布:淘宝模特培训 编辑:程序博客网 时间:2024/06/16 03:36

概述


这里介绍下Android中利用ALooper进行消息传递和处理的用法及工作原理。

利用ALooper进行消息传递即处理涉及到的类关系图如下:

AMessage类:消息类,用于构造消息,并通过post方法投递出去由ALooperRoster 类中转给ALooper

ALooperRoster类:中转类,将消息中转给ALooper 或者 AHandleReflector

ALooper:与AHandle一一对应,负责存储和转发AHandle的消息

LooperThread:此线程循环调用ALooper的loop方法来转发消息

AHandleReflector类:消息处理类

 

下面依据图并结合具体代码介绍下消息传递及处理流程

 

流程代码分析


图中的箭头部分代表了调用顺序:

1 注册handle: 语句mLooper->registerHandler(mHandler);  这样就建立了ALooper与AHandle的一一对应关系,要发送给AHandle处理的消息,都会经过ALooper存储和转发

mLooper(new ALooper),
  mHandler(new AHandlerReflector<SimpleSoftOMXComponent>(this)),mLooper->setName(name);mLooper->registerHandler(mHandler);mLooper->start(         false, // runOnCallingThread         false, // canCallJava         ANDROID_PRIORITY_FOREGROUND);

看下registerHandler实现

ALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) {    return gLooperRoster.registerHandler(this, handler);}

主要是将ALooper和AHandle注册到ALooperRoster中,继续跟进

ALooper::handler_id ALooperRoster::registerHandler(        const sp<ALooper> looper, const sp<AHandler> &handler) {    Mutex::Autolock autoLock(mLock);      if (handler->id() != 0) {        CHECK(!"A handler must only be registered once.");        return INVALID_OPERATION;    }      HandlerInfo info;    info.mLooper = looper;    info.mHandler = handler;    ALooper::handler_id handlerID = mNextHandlerID++;    mHandlers.add(handlerID, info);      handler->setID(handlerID);      return handlerID;}

将ALooper与AHandle 信息存储在mHandles 列表中, 可以存储多个<ALooper,AHandle >

注册完成后调用start启动ALooper开始工作

status_t ALooper::start(        bool runOnCallingThread, bool canCallJava, int32_t priority) {    if (runOnCallingThread) {        {            Mutex::Autolock autoLock(mLock);              if (mThread != NULL || mRunningLocally) {                return INVALID_OPERATION;            }              mRunningLocally = true;        }          do {        } while (loop());          return OK;    }      Mutex::Autolock autoLock(mLock);      if (mThread != NULL || mRunningLocally) {        return INVALID_OPERATION;    }      mThread = new LooperThread(this, canCallJava);      status_t err = mThread->run(            mName.empty() ? "ALooper" : mName.c_str(), priority);    if (err != OK) {        mThread.clear();    }      return err;}

这里主要是构造了一个LooperThread线程,此线程会循环调用其threadLoop

virtual bool threadLoop() {    return mLooper->loop();}

来处理消息,loop代码后面来看

这里看下threadLoop 在基类Thread中的介绍

    // Derived class must implement threadLoop(). The thread starts its life
    // here. There are two ways of using the Thread object:
    // 1) loop: if threadLoop() returns true, it will be called again if
    //          requestExit() wasn't called.
    // 2) once: if threadLoop() returns false, the thread will exit upon return.
    virtual bool        threadLoop() = 0;

这里的意思是 当threadLoop返回true时,会循环调用此方法,否则就终止线程

因此当threadLoop一直返回true,则可以看成是一个循环。

 

2 发送消息:通过构造AMessage对象,初始化参数后调用post方法发送

sp<AMessage> msg = new AMessage(kWhatSendCommand, mHandler->id());msg->setInt32("cmd", cmd);msg->setInt32("param", param);msg->post();

void AMessage::post(int64_t delayUs) {    gLooperRoster.postMessage(this, delayUs);}


3 中转:消息通过ALooperRoster来转发给ALooper

status_t ALooperRoster::postMessage(        const sp<AMessage> &msg, int64_t delayUs) {    Mutex::Autolock autoLock(mLock);    return postMessage_l(msg, delayUs);}

status_t ALooperRoster::postMessage_l(        const sp<AMessage> &msg, int64_t delayUs) {    ssize_t index = mHandlers.indexOfKey(msg->target());      if (index < 0) {        ALOGW("failed to post message. Target handler not registered.");        return -ENOENT;    }      const HandlerInfo &info = mHandlers.valueAt(index);      sp<ALooper> looper = info.mLooper.promote();      if (looper == NULL) {        ALOGW("failed to post message. "             "Target handler %d still registered, but object gone.",             msg->target());          mHandlers.removeItemsAt(index);        return -ENOENT;    }      looper->post(msg, delayUs);      return OK;}

从mHandlers中找到已经注册过的对应的ALooper对象,并调用post方法

4 ALooper存储消息

void ALooper::post(const sp<AMessage> &msg, int64_t delayUs) {    Mutex::Autolock autoLock(mLock);      int64_t whenUs;    if (delayUs > 0) {        whenUs = GetNowUs() + 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;      if (it == mEventQueue.begin()) {        mQueueChangedCondition.signal();    }      mEventQueue.insert(it, event);}

从代码里可以看到,消息存储在了mEventQueue中,mEventQueue 是封装了AMessage的结构体

 

5 ALooperRoster 中转

前面说了,LooperThread会调用threadLoop方法

virtual bool threadLoop() {    return mLooper->loop();}

实际调用的是ALooper的loop方法,而且如果loop返回true,则会循环调用

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;        int64_t nowUs = GetNowUs();          if (whenUs > nowUs) {            int64_t delayUs = whenUs - nowUs;            mQueueChangedCondition.waitRelative(mLock, delayUs * 1000ll);              return true;        }          event = *mEventQueue.begin();        mEventQueue.erase(mEventQueue.begin());    }      gLooperRoster.deliverMessage(event.mMessage);      // 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;}

代码主要是做如下工作:查看mEventQueue是否有message,如果有,且时间正确,则调用gLooperRoster.deliverMessage中转出去

而ALooperRoster实际代码为

void ALooperRoster::deliverMessage(const sp<AMessage> &msg) {    sp<AHandler> handler;      {        Mutex::Autolock autoLock(mLock);          ssize_t index = mHandlers.indexOfKey(msg->target());          if (index < 0) {            ALOGW("failed to deliver message. Target handler not registered.");            return;        }          const HandlerInfo &info = mHandlers.valueAt(index);        handler = info.mHandler.promote();          if (handler == NULL) {            ALOGW("failed to deliver message. "                 "Target handler %d registered, but object gone.",                 msg->target());              mHandlers.removeItemsAt(index);            return;        }    }      handler->onMessageReceived(msg);}

主要就是调用AHandle的onMessageReceived进行处理

 

6 AHandle处理函数执行 

 

这样一个消息从给投递到处理流程就结束了。 理清调用关系:主要是到ALooper中暂存,并借由全局变量gLooperRoster中转,完成了消息的传递。


【结束】 

原创粉丝点击