*声明
*构造活动对象
*添加活动对象到活动调度器
*实现请求函数
*实现RunL()
*实现DoCancel()
*重写RunError()
*析构活动对象
*声明
- 所有的活动对象都是直接或是间接地派生于CActive
- CActive声明于e32base.h
Class CMyActive : public CActive
{
public:
static CMyActive* NewL();
CMyActive();
~CMyActive();
Void ConstructL(); //这个函数中实现活动对象注册到线程中的活动调度器中
Void InvokeAsynFunc(); //异步函数调用请求
Virtual void RunL(); //异步函数的事件完成后的处理函数
Virtual void DoCancel(); //请求取消函数
Virtual void Tint RunError(Tint err); //错误处理函数
}
*构造活动对象
- 构造时需要指定活动对象的优先级
- 一般情况下,优先级都设为标准优先级,比如
CMyActive :: CMyActive() : CActive(CActive :: EPriorityStandard)
{
}
*添加活动对象到活动调度器
- 为了让活动调度器明确活动对象的存在,以及接收和处理信号量,需要将活动对象加入调度器
- 这通常在第二阶段构造函数完成,比如
CMyActive :: ConstructL()
{
CActiveScheduler :: Add(this);
}
*实现请求函数
- 活动对象中至少需要实现一个函数来调用异步函数
- 调用异步函数时,传入活动对象的成员变量iStatus
- 调用异步函数之后,调用基类函数SetActive()来标识该活动对象有一个未处理的异步函数调用,比如
Void CMyActive :: InvokeAsyncFunc(TAny* aArg)
{
AnAsyncCall(aArg, iStatus);
SetActive();
}
*实现RunL()
- 必须实现RunL()函数来实现异步函数的完成事件
- 在RunL()函数中可以检查iStatus成员变量的值,用来判断当前异步函数的状态,比如
Void CMyActive :: RunL()
{
If (iStatus == KErrNone)
{
//添加事件完成的处理代码,也可以发起另外的请求
}
Else
{
//添加错误处理代码
}
}
*实现DoCancel()
- DoCancel()是基类的一个纯虚函数,必须在派生类中重写
- DoCancel()不会被直接调用,而是通过CActive :: Cancel() 得以调用
- 只有当活动对象在等待异步函数完成的时候,Cancel()才会调用DoCancel()
*重写RunError()
- 可以重写RunError(TInt aErr)函数来处理活动调度器在调用RunL()函数时发生异常退出的情况
- 一旦错误被处理,该函数应该返回KErrNone,避免活动调度器再次处理该事件
*析构活动对象
- 活动对象的析构函数应该首先调用Cancel()来终止所有的未完成的请求
- 释放活动对象占用的所有系统资源,包括句柄
- 基类析构函数是虚函数,它会检查活动对象的当前状态