一、 绪论
本章节讨论Series 60 C++程序的设计和实现。我们假设读者熟悉C++,具备UML的基础知识,并且已经读过了《面向C++开发者的Series 60应用程序介绍》。
概况
本章节介绍了Series 60 C++的程序设计。设计中某些要素不在本文讨论范围中,请参考提供的其他文档。
本文从介绍S60程序开发框架开始,描述了特定的S60控件,最后讨论在开发C++程序时需要考虑的一些问题。
二、 Series 60程序开发框架
1) Series 60程序结构
Series 60在Symbian操作系统的基础Uikon用户界面层之上增加了专有的Avkon用户界面层。Avkon提供了专为S60设备设计了一系列控件集和程序框架。我们希望读者能够阅读S60 SDK提供的示例程序(存放在SDK子目录Series60Ex中),学习使用Avkon控件和应用设计的方法。S60 SDK为Microsoft Visual C++提供了向导程序,利用该向导我们可以得到各类型程序的基本类框架。
图一:组成S60应用程序的类之间关系
S60程序的四种主要的框架类如下:
l Application类:作为S60程序框架中的启动对象,定义了应用程序的属性。Document文档类由Application类创建。Application类的基类为CAknApplication。
l Document文档对象:用于存储应用程序的持久性状态(Persistent State)。应用程序必须有Document类的实例。存在的Document实例有可能只是用来运行AppUi。Document基类是CAknDocument。
l AppUi类:负责程序事件处理,包含对选项菜单命令的处理、打开/关闭文件以及程序失去焦点事件等的处理。通常,AppUi没有屏幕显示,他将屏幕绘画和屏幕相关的交互操作指定给其所有的View视图对象完成(AppUi可以拥有多个View对象)。多个View视图之间切换由AppUi完成。AppUi的基类是CAknAppUi或CAknViewAppUi。
l View视图类负责在屏幕上显示数据,以让用户操作。通常来讲,通过设计模式中的观察者机制,由模型状态告诉View视图更新,而View视图同样的将用户命令返回给AppUi。注意,在S60 SDK中,常用术语“容器(Container)”代表View视图,这两者是一样的。View视图继承自CCoeControl或者CAknDialog,当应用程序使用Application/View架构设计时,View视图继承自CAknView。
MVC模式中的Model/Engine通常有自己的类库实现,它将应用程序的功能封包,处理数据的持久性和算法。
程序框架创建Application对象,Application对象则构造Document对象,Document对象之后建立AppUi对象。AppUi构造并且拥有Model/Engine对象和视图。
2) Series 60程序类型
Series60程序有三种类型:
l 基于对话框的应用程序,其主视图是一个对话框。这种类型的好处是:对话框的框架处理掉了很多的事件,比如焦点状态。通常这类程序用于简单的UI交互情况。
l 使用View视图类型的应用程序。(自定义容器控件)
l 使用Application/View架构。这是一种高级的设计,应用程序生成单个或多个视图,使其他的应用可以访问这些视图。例如,外部的应用程序可以使用电话中已有的短消息应用程序(程序中的View对象)来发送短消息,而不用自己在应用程序中实现一个消息部件。AppUi必须从CAknViewAppUi继承,视图类必须从CAknView继承。
更多的有关这三种类型程序和使用信息请参见S60程序框架手册(S60_Application_Framework_Handbook.pdf)。
3) Series 60代码中进行异常处理
一个应用程序通常包含许多对象,其中一些对象可能很复杂,包含着许多其它部件。在类似智能手机这样的资源受限的设备上,某些情况下,程序或者系统控件需要的资源无法获得。有时内存可能不足。在内存不足的情况下,如果需要生成复杂对象,开发者很有必要编写代码使得生成时即便失败也是“优雅”的失败。Symbian操作系统有着自己的异常处理机制,在S60的2.0开发平台中可以使用。对于S60开发者来说,理解Symbian OS的才异常处理机制和代码习惯,并且严格的遵守代码习惯,是非常重要的。
由于对象分配堆内存有可能失败(在Symbian OS的术语中称为Leave),并且S60设备会有内存大小的限制,内存管理显得非常重要。标准的Symbian OS中构造复杂对象的方法是使用“清除堆栈”的两阶段构造法。在构造期间,对象的本地指针压入“清除堆栈”中。异常处理通过Leave机制完成。系统中有些API调用会返回错误代码,但是大部分API没有返回错误代码,而使用Leave机制,即代码立刻跳转到代码中早先设置好的点(即TRAP陷阱)。在Leave处理过程中,从最后一个TRAP陷阱后所有Push到“清除堆栈”中指向对象的指针都被移除,相应的每个对象都条用删除指令。使用Leave机制的函数的函数名医大写L结尾。
两阶段构造、清除堆栈、正确的函数命名、采用Leave机制的异常处理以及TRAP陷阱,这些都是所有S60 C++项目开发和实现的必要基础。
崩溃(Panic)是指不可恢复的错误,应用程序或者组件的线程被系统所终止或者遇到无法恢复的异常情况。更多Symbian OS异常处理的信息,请参考Series60 SDK文档。