在上一节里我们已经大致了解了活动对象的基本概念,要使用活动对象机制,需要用到活动对象、活动调度器、异步函数。我们想使用异步函数,要按照应用程序->活动对象->活动调度器->异步函数的流程来使用。接下来我们开始进入实战,使用活动对象。
一、创建活动调度器
我们知道,活动调度器是应用程序和异步函数之间的桥梁,应用程序使用活动对象通过活动调度器去截获异步函数的返回“完成”消息,并以事件的方式通知应用程序。
使用Carbide C++ 1.3,通过模板向导生成的控制台程序自动为我们生成了创建活动调度器的代码:
CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
CActiveScheduler::Install(scheduler);
CActiveScheduler::Install()方法调用以后,内部代码就会将scheduler指针赋值给CActiveScheduler类内部的静态指针,后面的代码就可以方便的使用CActiveScheduler类的静态方法,如:
IMPORT_C static void Add(CActive* aActive);
IMPORT_C static void Start();
IMPORT_C static void Stop();
Add()方法:将活动对象加入活动调度器中注册,以备使用
Start()方法:启动活动调度器,活动调度器将开始循环等待异步函数返回的通知消息
Stop()方法:停止活动调度器
二、创建活动对象
1、我们创建的活动对象必须派生自CActive类,CActive类已经为我们准备好了iStatus成员变量:
public:
TRequestStatus iStatus;
private:
TBool iActive;
另外一个成员变量iActive起着标识作用,证明该活动对象已经请求了异步函数,如:
RTimer::After(iStatus, 1000000);
SetActive();
SetActive()方法为基类CActive的方法,其实就是将iActive = ETrue;,用来标识活动对象已经调用了异步函数。所以,我们只要调用了异步函数,在调用异步函数的代码后面应该紧挨着调用SetActive()方法的代码。
2、有两个虚方法必须继承:
virtual void DoCancel() =0;
virtual void RunL() =0;
RunL方法:活动调度器接收到异步函数返回的“完成”消息后,遍历在其注册的所有活动对象,如果活动对象的iActive = ETrue且iStatus != KRequestPending则调用活动对象的RunL方法,并将iActive设置成EFalse,以防下次轮询时仍然调用此活动对象。
在这里“RunL”这个名字会让很多人产生歧义,我刚开始接触的时候总以为和J2me中的Runnable接口的run方法差不多。其实在这里把“RunL”改为“NotifyRequestCompleteL”更贴切些。
再次声明一下,调用异步函数时,参数TRequestStatus& status都是以引用的方式传递的,如:
IMPORT_C void After(TRequestStatus &aStatus, TTimeIntervalMicroSeconds32 anInterval);
所以异步函数内部可以改变status的实参,也就是改变活动对象的类成员iStatus。
DoCancel()方法:基类CActive中有取消异步函数的方法Cancel(),调用Cancel()后,活动对象会通过DoCancel()方法通知应用程序做取消方法的后期工作,如删除对象及回收指针等。注意:在应用程序中如果想终止活动对象,要使用Cancel()方法调用而不是DoCancel()方法。