symbian 学习笔记(1) 基础
-
(本文大多整理总结自网上)
Symbian 类似于c/c++中
TBuf<20> str; char str[20];
TPtr str; char * str;
HBufC * buf = HBufC::NewL(128); byte * buf = (byte*)malloc(128);
注意:
1每个后面都可以加上C,例如TBufC表示里面的值无法修改。
2 TBuf,TPtr,HBufC基本都具有类似于MFC的CString的方法,例如GetLenght(),取长度等等。
3 可以相互转化,例如 HBufC * buf = HBufC::NewL(64); TPtr p = buf->Des(); //注意因为HBufC带C是不可修改的描述符,所以如果我们要修改它,则需要用buf.Des()得到一个指向它的指针描述符。
4 _LIT(KSayHelloSTR,"Hello world."); //这里的KSayHelloSTR是另一种描述符TLitC &操作符能得到它的const TDesC*,而()操作符则得到它的const TDesC&。 KSayHelloSTR().Length(); //得到这个字串的长度
TBuf<256> str; str.Format(KFormatSTR,&KSayHelloSTR); //得到这个字串的引用地址 -
二:
CMyCls * me=new (ELeave) CMyCls; //用new (ELeave)开辟内存,直接使用它而不需要去判断是否构造成功,因为如果不成功会抛出错误并返回上层。 CleanupStack::PushL(mc); //我们可以在可能发生Leave之前将指针push到cleanupstack中,在正确完成之后再将它pop出来,如果万一不成功,系统会帮我们将cleanupstack中的东西销掉
me->doSth1L();
me->doSth2L();
CleanupStack::PopAndDestroy(); -
三: 类的名称前缀有T、C、M和R四个,
分述如下:
T表示基本类,它位于栈里,就当作是一个结构吧。
C表示常规的类,继承于CBase的,这是C++标准的类的概念,所以有构造要析构。
M表示是一个接口,很好理解,它肯定含有纯虚函数。 R表示是一个系统资源,比如文件、网络等等,所以它肯定有Open有Close。
K开头表示常量、E开头表示枚举也要记得。 形参用a开头,类成员变量用i开头,这此规则我们在自动生成的代码中也能看到。
还有函数的命名上也有讲究,不过不是开头而是结尾:象L表示可能会有Leave,LC表示不但可能有Leave而且它会被自动放在CleanupStack中。 还有两个二阶段构造又有三个函数名称固定了:NewL、NewLC和ContructL。 -
四:活动对象和调度器 symbian支持多线程(它有一个RThread类)但却又不提倡大家使用多线程,理由一般是说应用更安全?代码更简单?不过我觉得最有说服力的是省电。 既然如此,那我们就不说“多线程”,说说“多任务”吧,活动对象(Active Object)提供了非抢占式的多任务协同处理机制,它不是多线程的,而是运行在一个单线程中。
AO机制包括两个类CActiveScheduler和CActive: 调度器CActiveScheduler:顾名思义它是协调多个活动对象的调度者。既然是非抢占式的,那它的调度原则是什么呢?教材上说法是:
A) 根据活动对象的优先级顺序对已注册的所有活动对象逐个检查。
B) 判断它是否是活动的(IsActive),且它的iStatus是否不为KRequestPending。
C) 满足则执行它的RunL方法。 活动对象CActive:这可以理解为一个“线程”,就象Java中的Runable。它受调度器的指挥,它的关键在于类型为TRequestStatus的iStatus成员变量。 一般情况下在CActive中会有一个异步操作(方法形参表中包括一个TReuqestStatus类型参数),如果没有也无所谓(根据上面的调度原则,只要保证它不为KRequestPending即可)。 因为GUI应用自带了CActiveScheduler,所以我们要做的事情就是实现一个派生于CActive的子类,重载方法RunL()、DoCancel()和RunError()。当然还应该有一个类似于Start的方法来启动它。
Start负责启动,一般是在这里去执行一个异步操作(比如加载JPEG的图像,如上篇所言;或者打开一个定时器,如书上例子)。如果没有异步操作的话,也可以在这里啥事都不做。但是无论如何,它的最后一行肯定应该是SetActive(),让自己成为活动状态。
RunL负责具体的工作,如果是刚才Start了一个异步操作,此时应该处理该操作结束后的事务(如上篇中加载了图像以后就可以显示到屏幕上了)。如果刚才没有Start一个异步操作,那现在也得做点事情了。
有一种情况,我们把一个大任务分解成多个小任务,放在RunL中来做,那就得再加一个状态TInt iState来记录此次回调应该做哪一步小任务了(每完成一个小任务就改一个iState的值,并且还得再SetActive,让这个活动对象继续处于活动状态,直到所有任务完成)。 DoCancel提供了用户可以中止活动任务的手段,而RunError则提供了错误处理的机会。 另外,在这个CActive的子类中,应该有一个地方(一般是在ConstructL中)将自己放入调度器的队列中,即调用CActiveScheduler::Add(this)。