3 Alooper分析

概述

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

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

3 Alooper分析_第1张图片

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中转,完成了消息的传递。


【结束】 

你可能感兴趣的:(3 Alooper分析)