Android native异步消息机制

谷歌在Android native层实现的一个异步消息机制,在这个机制中几乎不存在同步锁,所有的处理都是异步的,将变量封装到一个消息AMessage结构体中,然后放到队列中去,后台专门有一个线程会从这个队列中取出消息然后执行,执行函数就是onMessageReceived

AMessage类

struct AMessage : public RefBase {
    //构造函数,包括两个参数,第一个参数指明这是个什么消息,用于在onMessageReceived处理分支中进行匹配,第二个参数target用于后台线程在处理这个消息的时候知道发给哪个类处理
    AMessage(uint32_t what = 0, ALooper::handler_id target = 0);
    void setWhat(uint32_t what);
    uint32_t what() const;
    void setTarget(ALooper::handler_id target);
    ALooper::handler_id target() const;

    void clear();
    //这个消息类中定义了一堆set和find方法,用于在在传递消息过程中携带各种信息
    void setObject(const char *name, const sp &obj);
    void setBuffer(const char *name, const sp &buffer);
    void setMessage(const char *name, const sp &obj);
    bool findBuffer(const char *name, sp *buffer) const;
    bool findMessage(const char *name, sp *obj) const;
    void post(int64_t delayUs = 0);
protected:
    virtual ~AMessage();  析构函数
private:
    uint32_t mWhat;
    ALooper::handler_id mTarget;
    两个重要的私有成员变量
};

使用方法
正如开头部分看的那样,构造一个消息的过程如下:

void NuPlayer::start() {
    (new AMessage(kWhatStart, id()))->post();
}
void AMessage::post(int64_t delayUs) {
    gLooperRoster.postMessage(this, delayUs);
}

AHandler类分析----消息处理类的父类

struct AHandler : public RefBase {
    AHandler()
        : mID(0) {  // mID的初始值为0
    }
    ALooper::handler_id id() const {
        return mID;   //id()这个函数用于返回内部变量mID的值,其初始值为0,但是会通过setID函数设置
    }
    sp<ALooper> looper();
protected:
    virtual void onMessageReceived(const sp &msg) = 0;
private:
    friend struct ALooperRoster;
    ALooper::handler_id mID;
    //下面这个函数正式在其友元类ALooperRoster的registerHandler中调用的
    void setID(ALooper::handler_id id) {
        mID = id;
    }
};
ALooper::handler_id ALooperRoster::registerHandler(
        const sp looper, const sp &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);
    //针对每个handler调用registerHandler的时候都会设置一个独一无二的handler_id,最后发送消息进行处理的时候就是通过这个独一无二的handler_id这个变量找到处理handler类的。
    return handlerID;
}    

在这个函数中针对这个looper和handler会构造一个HandlerInfo结构体,然后放到pair容器中。一个looper可以有多个handler,但是一一个handler只能跟一个looper。

ALooper类

struct ALooper : public RefBase {
    typedef int32_t event_id;
    typedef int32_t handler_id;
    ALooper();
    // Takes effect in a subsequent call to start().
    void setName(const char *name);
    handler_id registerHandler(const sp &handler);
    void unregisterHandler(handler_id handlerID);
    status_t start(
            bool runOnCallingThread = false,
            bool canCallJava = false,
            int32_t priority = PRIORITY_DEFAULT
            );
private:
    friend struct ALooperRoster; 
    struct Event {
        int64_t mWhenUs;
        sp mMessage;
    };
   //后台存放事件的链表
    List<Event> mEventQueue;
    struct LooperThread;
    //后台处理线程
    sp<LooperThread> mThread;
    void post(const sp &msg, int64_t delayUs);
    bool loop();
};

ALooper 里面用Condition 做消息通知, List存储消息

能作为handler进行注册的类都必须是继承自AHandler这个类,注册的过程也是交给
gLooperRoster处理。

AMessage类:

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

ALooperRoster类:中转类

将消息中转给ALooper 或者 AHandleReflector

ALooper

负责存储和转发AHandle的消息

LooperThread:

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

AHandleReflector类

消息处理类

使用方法
1.开始会创建一个ALooper对象, mLooper->start(…)

2.然后会实现一个AHandler的子类,
mLooper->registerhandler(objectXX)

子类实现一个onMessageReceived(XXXX),做收到消息的处理。

3.最后创建消息进行投递进入Message Queue。
创建AMessage里面,需要指定handleid,才能知道目标是发给谁。

mLooper(new ALooper)
mLooper->setName(name);  

mLooper->start(  
         false, // runOnCallingThread  
         false, // canCallJava  
         ANDROID_PRIORITY_FOREGROUND); 
mPlayer = new NUPlayer;
mLooper->registerHandler(mPlayer);  
//mPlayer是一个AHandler
mReflector =new AhandlerReflector<RTSPSource.(this);
mLooper->registerHandler(mReflector); 
(new AMessage(kWhatStart,id()))->post()

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值