彻底理解 Symbian 活动对象
2010-08-24 05:50:00 来源:WEB开发网5、iStatus = KRequestPending
在以上代码StartL方法中,异步函数调用之前,首先要将iStatus设置为KRequestPending以便活动调度器遍历时匹配。
6、请求异步函数并发送iStatus
在StartL方法中,iTimer.After(iStatus, aDelay);这行代码传递了成员变量的引用并调用了异步函数iTimer.After。
7、SetActive
调用基类CActive的SetActive方法,方法内部将iActive设置成ETrue,以便活动调度器遍历时匹配。
8、启动活动调度器
10、查找对应的活动对象
我们在上一节已经通过分析并还原了CActiveScheduler::Start()方法的伪代码,此代码块在另外一个线程遍历所有向调度器注册的活动对象,查看对象的iStatus不为KRequestPending且iActive为ETrue。因为异步函数服务器完成了请求的工作以后,会改变iStatus的实参,使其不等于KRequestPending,再加上活动对象在调用完异步函数返回后马上改变了iActive值为ETrue,所以活动调度器只要判断iStatus != KRequestPending && iActive == ETrue则可以知道哪一个活动对象所请求的异步服务已经完成。
9、WaitForAnyRequest()等待异步函数返回通知,11、RequestComplete()并将iStatus的值改变
当异步服务已经完成了所请求的工作,它会使用User::RequestComplete()发送一个通知,活动调度器会通过 User::WaitForAnyRequest()或RThread::WaitForAnyRequest()收到这个通知,随后遍历向其注册的条件匹配的活动对象(第8点下划线部分说明)。
12、调用RunL方法
如果找到了异步函数所对应的活动对象,则调用活动对象的RunL方法,RunL方法在TRAP宏里运行。如果RunL方法抛出异常,活动调度器会自动调用活动对象的RunError方法。因此大多数情况下不需要在RunL内编写异常捕获的代码。
活动对象调用完RunL方法后,将活动对象的iActive值设置为EFalse,以便在下次遍历集合时跳过已经处理过的活动对象。
如果没有找到异步函数所对应的活动对象,活动调度器将抛出一个“信号迷失”异常。
13、CActiveScheduler::Stop()
停止活动调度器,停止监控异步函数返回的信号。
二、活动对象专属错误-“信号迷失”
从上面的分析我们知道,活动调度器会拦截异步函数返回的消息,随后遍历活动对象集合找到相应的活动对象调用,如果没有找到则抛出“信号迷失”异常。有以下两种方法会导致“找不到活动对象”的发生:
更多精彩
赞助商链接