Symbian编程总结-基础篇-活动对象正解(2)-使用活动对象

在上一节里我们已经大致了解了活动对象的基本概念,要使用活动对象机制,需要用到活动对象、活动调度器、异步函数。我们想使用异步函数,要按照应用程序->活动对象->活动调度器->异步函数的流程来使用。接下来我们开始进入实战,使用活动对象。

一、创建活动调度器

我们知道,活动调度器是应用程序和异步函数之间的桥梁,应用程序使用活动对象通过活动调度器去截获异步函数的返回“完成”消息,并以事件的方式通知应用程序。

使用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()方法。

时间: 2024-11-05 09:12:06

Symbian编程总结-基础篇-活动对象正解(2)-使用活动对象的相关文章

Symbian编程总结-基础篇-集合与缓冲区(2)-验证RArray::Append

Symbian编程总结-基础篇-集合与缓冲区(2)-验证RArray::Append是否保存对象副本 一.验证栈对象会自动销毁 我们知道,在C++中,在函数中创建了栈对象,函数退出时,该栈对象会自动销毁(栈指针后移了,栈内存会被覆盖).如何验证这一点?我们需要在函数外定义一个整形变量,在函数内将该函数内获取了变量的地址,在函数调用完毕后,将地址还原成对象: TInt iAddr; /** * 将地址还原成描述符对象并显示出来 * @param aAddr 地址 */ LOCAL_C void P

Symbian编程总结-基础篇-动态缓冲区(1)-回顾HBufC

当数据尺寸在编译期不固定,而在运行期有可能要扩展到很大尺寸时,动态缓冲区在保存二进制数据方面显得非常有用.我们可以使用C++数组保存二进制数据,然后调用类似于memcpy的函数去动态的改变数组所占用空间的大小:我们还能够使用HBufC描述符,获取其可修改的描述符向其写入数据,然后调用ReAlloc方法扩展数组.以上两点方法可行,但是不好,因为我们得自己管理内存的分配.Symbian C++考虑到了这一点,于是引入了动态缓冲区的概念. 基于堆的缓冲描述符HBufC的前缀H显然不符合Symbian

Symbian编程总结-基础篇-活动对象正解(4)-异步函数的同步调用

在上一节里我们深入了解了活动对象.活动调度器及异步函数服务器的工作原理及运行机制,想必大家对活动对象的机制及体系结构的运用已经了如指掌.但是大家有没有觉得异步函数使用起来比较麻烦呢?难道非要使用活动对象,非得以"异步"的方式调用异步函数吗?这一节将为大家解决这个问题:异步函数的同步使用. 一.使用CActiveSchedulerWait类 在以前的文章"Symbian编程总结-界面篇-打开jpeg/gif/png图像"里我们已经看到了CActiveScheduler

Symbian编程总结-基础篇-活动对象正解(3)-活动对象的工作原理

在上一节里我们已经知道如何创建和使用活动对象,大家对活动对象的创建.使用都有了一定的了解.在这一节里我将深入活动对象机制,分为"活动对象的工作流程"."信号迷失错误"两个部分,为大家剖析活动对象的工作原理. 一.活动对象工作流程 首先我们用时序图来说明一下应用程序.活动对象.活动调度器及异步函数服务器之间创建及调用的流程: 下面我们针对每一个步骤结合代码(点击此处下载代码)进行说明: 1.创建并安装活动调度器: CActiveScheduler* scheduler

Symbian编程总结-基础篇-活动对象正解(1)-理解活动对象

Symbian OS中的活动对象的使用无疑是最基础的.最频繁的.最重要的.什么是活动对象呢? 大家学习一个新的事物时,总是会将这个新的事物与自己认知的事物相比较,从而达到快速学习的目的.我开始学习Symbian的时候,我查看很多Symbian书籍.网上很多Symbian教程都将活动对象与多线程联系到一起,我也总是会把活动对象想象成一个线程.然而,经过了更深入的接触,我发现并不像我想象的那样. 现在,我在此向你保证:活动对象和多线程没有任何关系!不要拿平时做多线程的思想去理解活动对象! 活动对象可

Symbian编程总结-基础篇-描述符(1)-描述符简介

一.强化印象 在学习描述符之前,首先要理解Symbian中描述符的作用.在Symbian中,没有提供专门用来处理字符串的类,它把字符串和二进制缓冲区看成是同一类数据,有一套专门的类去管理,这一套类的类关系图层次结构如下图所示: 图一. 描述符类的层次关系 上图所示的类统称为"描述符",Symbian用"描述符"来管理字符串,其中,TDesC.TDes.TBufCBase为抽象类. 我们首先来举一个简单的例子,来强化我们对描述符的理解.如果我们由一个字符串"

Symbian编程总结-基础篇-类类型

原文出自:http://discussion.forum.nokia.com/forum/showthread.php?t=68969 译自Developer Library » Symbian OS Guide » Essential idioms » Class types 概要 Symbian OS上的应用程序使用4种常用的类,它们是: 以T开头的值类,这种类不拥有任何外部对象,只是通过指针直接引用或通过句柄间接引用外部对象. 以C开头的基于堆分配的类,这种类全部是从CBase派生过来的.

Symbian编程总结-基础篇-集合与缓冲区(1)-RArray和RPointerArray

Symbian OS不支持STL,主要原因是因为STL覆盖的面太广,不适合在内存受限的设备上使用. 在这里我们首先学习RArray模板类.如果您有java或者.net方面的经验,Symbian中的RArray和RPointerArray类似于java中的Vector<>或.net中的List<>. 注意事项: RArray和RPointerArray都是基于模板的 RArray的模板参数应该为R类或T类,而RPointerArray的模板参数可以是任意类型 RArray是固定长度对

Symbian编程总结-基础篇-描述符(2)-TDesC8与TDesC16之间的互转

1.使用Copy _LIT8(KTestStr, "This is a string"); TBufC8<50> buf(KTestStr); TBuf<100> newBuf; newBuf.Copy(buf); TBuf8<50> newBuf1; newBuf1.Copy(newBuf); 2.使用CCnvCharacterSetConverter类 _LIT8(KTestStr, "This is a String"n&q