【android12】【AHandler】【4.AHandler原理篇ALooper类方法全解】

AHandler系列

【android12】【AHandler】【1.AHandler异步无回复消息原理篇】-优快云博客

【android12】【AHandler】【2.AHandler异步回复消息原理篇】-优快云博客

【android12】【AHandler】【3.AHandler原理篇AHandler类方法全解】-优快云博客

其他系列

本人系列文章-优快云博客


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类

//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

// static
int64_t ALooper::GetNowUs() {//获取当前时间
    return systemTime(SYSTEM_TIME_MONOTONIC) 
}

2.3 ALooper::ALooper构造函数

会清除旧的Ahandler

ALooper::ALooper()
    : mRunningLocally(false) {
    gLooperRoster.unregisterStaleHandlers();//清除旧的Ahandler。从保存注册Ahandler的列表中删除
}

2.4 析构函数

调用stop函数,让looper线程停止循环,并释放线程资源

ALooper::~ALooper() {
    stop();
}

2.5 ALooper::setName

void ALooper::setName(const char *name) {//为looper设置名称
    mName = name;
}

2.6 ALooper::registerHandler

注册Ahandler并将其保存到一个容器中。

ALooper::handler_id ALooper::registerHandler(const sp<AHandler> &handler) {//注册Ahandler,用一个map保存alooper和Ahandler的对应关系
    return gLooperRoster.registerHandler(this, 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
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值