一、使用活动对象的原因
Symbian OS广泛使用了事件驱动模型,活动对象将传统的等待循环封装到一个类中,在同一个线程中运行的活动对象之间切换的代价比线程上下文的切换代价低得多,所以使用活动对象更适合Symbian OS的事件驱动多任务。同样使用抢占式多线程对于事件处理也不方便,因为抢占式多线程需要通过例如互斥体、信号量等同步原语来保护共享对象,在Symbian OS 要实现共享非常难。所以利用活动对象实现事件驱动模型最为合适。
注意:一旦一个活动对象在处理事件,它就无法被另一个活动对象的事件处理程序抢占,也就是如果对实时性要求较高的应用,应考虑用高优先级线程和进程来实现。
二、活动对象的应用
1、构造
和线程类似,活动对象也有一个优先级值来决定它们如何被调度。从CActive派生的类必须调用基类中的作为保护成员的构造函数,并传递一个参数来设置活动对象的优先级。
2、提交请求
活动对象类会向调用者提供公有方法用以发出请求,也就是说通常拥有一个发出异步完成请求、生成事件的对象,例如RTimer类的定时器对象。
- 请求方法应检查确认在试图提交另一个请求之前没有请求已经被提交。
- 活动对象应向服务提供者发送请求,传入其TRequestStatus类型的iStatus成员变量作为参数。
- 请求成功提交了,请求方法将调用CActive基类的SetActive()方法,向活动调度器指明请求是已经被提交还是现成被选中。
3、事件处理
活动对象必须实现CActive基类跌纯虚成员函数RunL(),当异步服务提供者完成事件发生,而且活动调度器选择了活动对象处理该事件时,调用活动对象的RunL()函数。
注意:每个活动对象必须通过实现基类CActive的成员纯虚函数RunL()来处理完成事件。
4、撤消
调用Cancel()进行撤消,该方法调用纯虚函数DoCancel()。用户需要重载DoCancel(),进行撤消工作以及请求相关的必要清除工作。
5、错误处理
活动对象提供了RunError()虚函数,当活动对象的RunL()方法发生异常退出时,活动调度器调用这个方法。
6、析构
CActive派生类的析构函数在清除过程执行前总是坑用Cancel()来中止所有选定的请求。
(未完待续)