Symbian OS 精要

来源:互联网 发布:seo研究中心vip课程 编辑:程序博客网 时间:2024/05/04 16:28

一般诀窍


1.‘Symbian 开发师网络’提供大量信息资源,协助您为
Symbian OS 操作系统编写应用程序。您应经常访问
www.symbian.com/developer 网站以便获取最新的
SDK、技术资料、编码范例和白皮书。您从开发师网
络网站能够获得:
• Symbian OS‘常见问题’(FAQ) 库。这是一个对开发者
来说极有价值的信息库,涵盖了最常见的设计和编码
问题。
• 许多白皮书。其中包括《Symbian OS C++ 编码标准》。
在Symbian OS 本身的开发过程中,Symbian 设定了
若干重要的编码习惯方法和规范。《编码习惯方法白
皮书》向外部程序员解释这些习惯方法。通过采用这
些约定俗成并经过试用和验证的规范,您可以通过开
发Symbian OS 软件受益到Symbian OS 在自身开发
中获得的宝贵经验。
• Symbian OS Developer Library,标准API 参考文档、
Symbian OS 指南。
• 下载应用程序范例、应用程序库、属于Symbian OS
但不一定被装到所有手机上的‘可选’系统API、使
较新Symbian OS 版本上的API 能够在较旧版本上运
行的移植程序库等等程序工具。
• 关于调试工具和开发工具方面的信息。
• 新闻组论坛
(www.symbian.com/developer/leters/forum.html),使
您能够从Symbian 工程师和更广的开发者团体那里
获得指导。有各种不同论坛,从针对C++ 和Java 的
具体问题、到硬件和Symbian 签名等等,涉及到开
发工作的各个方面。
2. 注册并订阅Symbian 开发者网络期刊
(www.symbian.com/developer/letters/index.html) ——
该期刊通过电子邮件每月发布一次, 是了解与
Symbian 开发者相关的最新消息的最佳途径。
3. 采用Symbian OS 的移动电话生产商也拥有自己的开
发者项目。您也应该在他们的网站注册,以便获取针
对某种具体型号的电话的最新信息和诀窍。
4. 获得认证!
(www.symbian.com/developer/academy/index.html)
《Symbian 认证程序员》证书能够向雇主显示您是一
名合格的Symbian 工程师,并有助于客观地评估您
所掌握的Symbian OS 相关技术的各项能力。
5.‘Symbian 签名’(Symbian Signed)旨在推广设计
Symbian OS 应用程序的各种最佳范例。通过Symbian
签名的应用程序均遵守行业认同的质量标准并迎合网
络运营商对签名应用程序的要求。请到‘Symbian 签
名’网站(www.symbiansigned.com)获取关于
Symbian 签名的更多信息。
6. 除了Symbian 和相关生产商之外还有一个活跃的开
发者社区。请访问
www.symbian.com/developer/about/trdprtysites.html
以查找众多知名的第三方开发者网站的链接。
7. 最后,现在关于Symbian OS 的出版物日益增多。
Symbian 出版社
(www.symbian.com/developer/books/index.html)出版
的一系列Symbian OS 相关主题的书籍,目的都是帮
助您更轻松的编写更可靠的Symbian OS 代码。


设计诀窍


1. 最重要的设计诀窍是将‘引擎’代码与用户界面(UI)
代码分开,分为不同的模块。这样设计有助于您的程
序在不同用户界面系统之间的移植,Symbian OS 本
身也采用这种设计。
方法之一是在二进制级就进行这个区分。将所有非用
户界面相关代码放到独立的引擎.DLL 文件中。您的程
序中用户界面相关的代码可以链接到这个。DLL 文件,从而访问引擎获取其提供的功能。另一种方法是在源
代码级做出区分。应用程序生成为一个单一的.APP 文
件,但将‘引擎’相关代码和用户界面相关代码分到
不同的.CPP 和.H 文件中,以便于管理和调试。
编码时采用这种设计,您可以减轻移植到新的用户
界面平台时产生的负担;纯引擎代码经常可以不经
修改就在任何用户界面平台上运行。这意味着移植
到新用户界面时您只需要移植和优化已经单独分开
的用户界面层就行了。
2. 设计时要牢记地方化支持。千万不要将字符串或文字
‘硬编写’到您的源文件中——应使用Symbian OS 提
供的资源文件机制来储存字符串。
3. 应坚持使用软件开发包(SDK)和Symbian OS 发布
版本明确支持并提供文档的API。使用不受支持或
‘不推荐使用’(deprecated)的API 将给您的应用程序
带来潜在的问题—— Symbian 保留在未来的版本中更
改或者移除不应被外部开发者使用的API 的权利。
4. 不要假定所有的‘系统’文件都会出现在所有电话上。
持有Symbian OS 执照的厂商可以灵活的改制其手
机;基于同一平台的电话如果由不同的生产商生产很
可能包涵不同的支持文件——从而,比如说,如果为您想要播放的音响片段编写固定的地址,此代码将不
会保证具有良好的移植性。您至少应该考虑如果未来
的手机没有这个系统文件,您将如何处理出错状态的
问题。


编码诀窍


以下是您在编写代码时应该记住的一些一般诀窍。
1. 确保您的应用程序能够对系统关机事件做出响应。在
您的AppUi::HandleCommandL()方法中,必须要
对EEikCmdExit(以及任何特定平台相关的事件,
例如Series 60 上的EAknSoftkeyBack)做出响应。
2. 要对外来系统事件做出响应。请牢记,您的应用程序
是在一个多任务电话系统上运行,您需要将注意力集
中于刚获得的/丢失的事件上,以确保当用户获得一
个高优先级的通知时您能够做出正确响应。例如,正
打进来的电话会干扰您的应用程序的运行,这时应确
保您已保存了系统状态和数据(即:您需要对标准的
“背景”事件采取适当的行动——请参阅SDK)。一般
说来,系统框架会处理这个问题,您不需要采取任何
特殊行动——但一定要确保您没有妨碍系统框架的正
常操作。
3. 内存处理是Symbian OS 需要考虑的一个重要课题。
在这一点上,应注意电话有时会不同于模拟器。因此
在将您的应用程序呈交给“Symbian 认证签名”进行
测试之前,务必确保已在实际电话设备上测试了您的
程序。
4. 内存堆栈空间有限!应尽可能将对象放到内存堆中,
而不要放到栈里。KERN-EXEC 3 异常(panic)发生的
主要原因之一就是栈的破坏/溢出。
5. 应用程序发生异常(panic) 表明您的代码中一定有错
误。以下是一些主要、常见的错误:
• 忘记将非对象成员、被分配到堆的变量加到
CleanupStack 上。
• 将成员变量放到CleanupStack 上——这一点要千万避
免;在析构函数中将这些变量删除就可以了。
• ‘重复删除’——例如,没有正确的从CleanupStack
上Pop()出已经被销毁的对象,造成CleanupStack
以后试图再次删除它。或者使用过一个对象之后将
其删除但忘记将其值设成NULL,从而在析构函数又
试图删除一次。
• 用可能不存在于您的析构函数中的变量调用函数。
例如,以下代码可能导致异常,因为有可能您在分配
内存之前您的对象已经被销毁,或者在应用程序的另
一处已经删除了该内存,这样iSomeServer 就会处
于NULL:
CMyClass::~CMyClass()
{
iSomeServer->Close();
delete iSomeServer;
}
应该如下编写代码:
CMyClass::~CMyClass()
{
if (iSomeServer)
{
iSomeServer->Close();
delete iSomeServer;
}
}
• 在NULL 指针上调用函数。
• 函数调用另一个函数,而其使用的变量已经超出范畴,
例如:把一个栈变量传送到一个异步函数的回调
(callback) 里。
6. 在系统资源不够的情况下,得体的处理失效情况是非
常重要的。最受限制的资源通常是系统RAM,因此
您需要注意正确的处理内存不足的情况。采用‘两段
构造方法’和如下所述的CleanupStack 机制,对这
种防御性编程来说是必不可少和极其重要的。
7. 对带“R”字头、具备Close()方法的类,总是使用
CleanupClosePushL()。这将确保当Leave 事件
发生时,它们会被恰当的清除。例如:
RFile file;
User::LeaveIfError(file.Open(…));
CleanupClosePushL(file);

CleanupStack::PopAndDestroy(&file);
对用Release()或Destroy()的‘R’ 类,亦可使用
CleanupDeletePushL()及
CleanupReleasePushL()来取代Close()。
8. 另外,请记住CleanupStack 机制是可扩展的,面
对所有Leave 事件,都可以用它来有效的清除任
何对象。即使您需要处理的是较复杂的情况,也
不应该忽略采用正规的清理机制。欲进一步了解
TCleanupItem,请参阅Symbian OS Library 文档。
9. 倘若您意图对HBufC 变量重新分配资源,在清除它
们之后,总是将其设为NULL。由于HBufC 的资源
分配或其再分配可能会导致Leave 事件的发生,从而
可能会出现析构函数试图删除已经不存在的HBufC
变量的情况。当然,对于任何由堆分配资源的变量而
言都应如此,对HBufC 变量采取此做法更是已经成
为普遍的使用模式。
10. 当必须采用自己的TRAP 时,请勿忽略所有的报错。
常见的编码错误是:
TRAPD(err, DoSomethingL());
if (err == KErrNone || err ==
KErrNotFound)
{
// Do something else
}
这意味着其他错误码都被忽略。然而,倘若您非用上
述模式不可,应采用Leave 机制来处理其他错误:
TRAPD(err, DoSomethingL());
if (err == KErrNone || err ==
KErrNotFound)
{
// Do something else
}
else
User::Leave(err);
11. 不要延误将对象PushL()到CleanupStack 上。所
有新创建的对象(成员变量除外)应被立即压入该堆
栈。例如,下面的作法是错的:
void doExampleL()
{
CSomeObject* myObject1=new (ELeave)
CSomeObject;
CSomeObject* myObject2=new (ELeave)
CSomeObject;

// Do something here with thevariables
CleanupStack::PushL(myObject1);
CleanupStack::PushL(myObject2);
// Do something more with the variables

CleanupStack::PopAndDestroy(2);
// myObject2, myObject1
}
因为myObject2 的创建可能失败,造成myObject1
“悬”在那里不能被清理。应该这样来实现:
void doExampleL()
{
CSomeObject* myObject1=new (ELeave)
CSomeObject;
CleanupStack::PushL(myObject1);
CSomeObject* myObject2=new (ELeave)
CSomeObject;
CleanupStack::PushL(myObject2);

// Do something here with the variables

CleanupStack::PopAndDestroy(2);
// myObject2, myObject1
}
12. 注意,那些名称有大写字母C 结尾的函数(例如
NewLC())会自动把其对象置于CleanupStack。
您不应该自己来将这些对象压入CleanupStack,
否则该对象会入栈两次。当您创建非成员变量并为其
分配内存时,这些由C 结尾的函数很有用。
13.“两段构造方法”是Symbian OS 内存管理的关键
部分。基本原则是Symbian OS 中的构造函数或析
构函数永远不应该发生Leave。倘若一个C++ 构造
函数Leave,构造过程未完成的对象得不到清理,
因为还没有生成指针指向该对象。为此,Symbian
OS 中的构造函数仅将该对象实例化,而后调用该
对象的ConstructL()函数,在其中将成员数据
实例化。一旦ConstructL()发生Leave,标准
的析构函数将被调用来清除所有至此已被成功分
配的成员变量。在您的编码中照用这一设计模式
来防止内存泄漏,至为关键。当您写每一行代码
时, 都应该问自己:“ 这一行代码能否发生
Leave ?”假如回答为“是”,则应考虑“是否所
有资源都将被释放?”。
14. 编码中请勿使用_L()宏——而应使用_LIT()。_L()
自Symbian OS v5 起已是‘不推荐使用’(deprecated),
它的问题在于它将调用TPtrC(const TText*)构造
函数,该构造函数会调用strlen()函数来计算该字串的长度。虽然这不会带来额外的RAM 开销,却会
在运行时占用更多CPU 周期。相反,宏_LIT()直接
创建了一个在编译时就全部实例化的对象,节省了构
造TPtrC 的CPU 开销。当然,您首先应该考虑的是
否应该使用硬编码的字符串常量,因为当您将来地方
化(localize)您的程序时,这种常量类型的描述符
(descriptor) 可能需要重新编码。
15. 当在函数参数中使用描述符(descriptor) 时,应缺省
使用基类。在大多数情况下,以const TDesC& 形
式来传递描述符。对可修改的描述符,则应使用
TDes&。
16. 当在函数中传递或返回对象时,应确保如果您拥有该
对象的所有权,您应负责将其清除! Symbian 采取
的约定是:函数中的指针表示所有权转移到调用者,
而使用引用则表示被传递对象的所有权仍属于原所
有者。
17. Active Objects 是Symbian OS 的重要特性之一。请仔细
研究SDK 文档、Symbian Developer Network 白皮书,
以充分理解其工作原理。下面是一些有用的窍门:
• 在RunL()内无需使用TRAP()。Active Scheduler
本身会TRAP 函数RunL()并在其发生Leave 时
调用CActive::RunError()。
• 为此,您应实现自己的RunError()函数来处
理从RunL()的Leave 事件。
• 保证RunL()操作尽可能简短。长时间运行的
RunL()将阻塞其他Active Objects。
• 总是实现DoCancel()函数,总是在AO 析构
函数中调用Cancel()。
18. 您应尽可能利用Active Object 框架机制。对于使用电
池供电的设备,在一个循环中紧密不断地进行轮流
检测(polling) 是极其不适当的,将带来大量耗电。
写游戏时,对此尤需特别注意,详情参阅Symbian
Developer Network 网站的技术文档
(www.symbian.com/developer/techlib/papers/porting_
3D_games/XenGames_paper.pdf)。
19. ViewSrv 11 异常对于繁忙运行的程序(例如游戏)是
一个潜在的问题。当您的,或者其他任何程序中的
ViewSrv active object 不能及时响应View Server 时就
会导致此种异常。典型的最长回应时间
是10-20 秒。FAQ-0900 有详细解释,FAQ-0920 有针
对如何避免此类问题的实用技巧。二者均可从
www3.symbian.com/faq.nsf 网页上的Symbian OS
FAQ 数据库获取。
20. 您无需使用HBufC::Des()来进入一个HBufC 对
象。只需采用* 操作符来为HBufC 对象解除引用
(dereference)。这对于向某个接受TDesC&(上文的
推荐做法)的函数传递HBufC 参数时尤其有用。
21. 当使用标准的程序.INI 文件的功能时,(即在您的应用
UI 类中使用Application()->OpenIniFileLC();
API 时),确保将版本号信息写入流(stream) 中。这样
使您能够在未来新版本的程序中建立新的流,意味着
即使某个最终用户将来安装您的软件的新版本时,不
会因为在旧的.INI 文件中找不到正确配置或流时发生
异常。
22. 在您的程序中实现框架类(framework class) 时要
小心。应该始终从所提供的平台相关的框架类中继
承。例如,对UIQ 而言,不要从CEikAppUi 继承
您的AppUi 类,而应从CQikAppUi 继承。所有的
应用基类(CQikAppUi、CQikApplication、
CQikDocument)添加的功能支持更广的框架范围
来保证应用程序正确运行。


测试诀窍


1. 最重要的测试诀窍是,在用模拟器时(emulator),正
确的退出您的程序,而不是仅仅简单地关闭整个模拟
器。在调试模式中,在应用程序框架(application
framework)的关闭函数前后有内存及句柄检测代码,
当您退出应用程序时,此代码将被调用,从而可检测
到是否有内存泄漏或遗留句柄(例如R 对象)发生。
对UIQ 程序而言,为此目的习惯上在调试模式里提供
一个Exit 菜单选项。
2. 另外一个至关重要的诀窍是在发布您的程序之前确保
在.PKG 文件中包含了正确的平台相关信息。相关平
台相关信息字符串的详情请参照该平台的SDK。
www3.symbian.com/faq.nsf 上的Symbian OS FAQ 数
据库中的FAQ-0853 提供了有用的相关信息。
3. 在写.PKG 文件时,也要确保恰当的使用了“!:/”语
法。一般来说,您的应用程序应可从最终用户手机中
的任何盘中安装、运行。仅有极少量的文件需要放置
于C:/ 盘中(例如.INI 文件)。


调试诀窍


1. 总应先使用模拟器调试;大部分同时发生在模拟器与
硬件上的问题,使用模拟器调试会容易得多。
2. 在编写和调试新的控制类时,
把iEikonEnv->WsSession()
.SetAutoFlush(ETrue)置于您的AppUi 的
ConstructL()函数中。这意味着gc draw 指令
会在模拟器中立即显示,而不是在下一次冲刷(flush)
视窗服务器客户端缓冲时。编辑WSINI.INI 文件
(/epoc32/release/winscw/udeb/system/data/),确保
不存在关键字FLICKERFREEREDRAW。这意味着您可
以逐步运行draw 代码,并看到每行代码的效果。然
而,应确保此行代码不留在发布的软件中,因为这会
影响性能。
3. 应定时对源文件运行LeaveScan 工具。该工具可以检
测到所有可以Leave 的函数,并在其名称不以L 结尾
时报错,并提醒源文件中潜在的缺陷或疏忽。在检查
哪些代码应被允许Leave,并确保已正确处理此状况
时,该工具非常有效。参见
www3.symbian.com/faq.nsf 上的Symbian OS FAQ 数
据库里的FAQ-0291,下载该工具并进一步了解。
4. 如果您的程序在正常关闭时因内存泄漏而发生异常,
在MS Visual Studio 中可将泄漏的地址转换为CBase*
类型,从而查看该泄漏对象的类型。
5. 最近为对Symbian OS 开发者提供了新的功能:设备
上调试(on-target debugging)。虽然不是所有的SDK
及工具均已具备此功能,但大多数最近发布的SDK 及
IDE 支持此功能。如可使用此功能,请在发布您的程
序前使用它来检测任何潜在的手机硬件相关的缺陷。
进一步的信息,请阅读SDK 及IDE 文档。
6. 确保‘Just in Time’调试被启用:
• 确保在文件“/epoc32/data/epoc.ini”里删除了宏
“JustInTime 0”
• 注册表值做如下设定:
[HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/
Windows NT/CurrentVersion/AeDebug]
"UserDebuggerHotKey"=dword:00000000
"Debugger"="/"C://apps//Metrowerks//bin/
/IDE.exe/" -p %ld -e %ld"
"Auto"="0"
7. 审阅%Temp%epocwind.out 所含的纠错讯息。
8. 使用所有可用的开发工具,包括Lint、Leavesan、
HookLogger、Panix、D_EXC 来检查内存泄漏及其他
错误。这些工具及其他更多有用的工具可在Symbian
Developer Network 下载
(www.symbian.com/developer/downloads/tools.html)。
9. FAQ-1344 教您如何诊断并调试违反平台安全
(KErrPermissionDenied) 的故障,这有助于识
别您的程序所缺少的权限(capability)。  

原创粉丝点击