开发 BREW Extension

开发 BREW Extension

Developing the BREW Extension

田海立

<chsdate isrocdate="False" islunardate="False" day="7" month="5" year="2006" w:st="on"><strong style=""><span lang="EN-US">2006-5-7</span></strong></chsdate>

摘要

BREW 应用开发者的角度,探讨 Extension 的实现。

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-begin'></span><span style='mso-spacerun:yes'></span>TOC /o &quot;1-3&quot; /h /z /u <span style='mso-element:field-separator'></span></span><![endif]-->摘要... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877233 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->1<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200330033000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

1 BREW概览... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877234 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->1<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200330034000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

1.1 BREW简介... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877235 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->1<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200330035000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

1.2 BREW中的几个基本概念... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877236 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->2<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200330036000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

1.3 BREW模拟开发环境... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877237 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->2<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200330037000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

2 开发BREW Extension. <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877238 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->3<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200330038000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

2.1 Extension的应用场景... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877239 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->3<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200330039000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

2.2 文件组成... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877240 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->4<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200340030000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

2.3 Module Extension 中的关系... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877241 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->5<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200340031000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

2.4 实现Extension. <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877242 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->6<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200340032000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

2.4.1 类型定义... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877243 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->6<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200340033000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

2.4.2 AEEClsCreateInstance() 的实现... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877244 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->7<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200340034000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

2.4.3 构造函数的实现... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877245 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->8<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200340035000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

3.2.4 SampleExt IBase 中方法的实现... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877246 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->9<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200340036000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

3.2.5 JustSayHello() 方法的实现... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877247 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->10<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200340037000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

3.2.6 ClinetApp 事件处理... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877248 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->10<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200340038000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

2.5 执行序列... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877249 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->11<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200340039000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

总结... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877250 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->13<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200350030000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

参考资料及进一步参考... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877251 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->13<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200350031000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

关于作者... <!--[if supportFields]><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'><span style='mso-element:field-begin'></span></span><span style='color:windowtext;display:none;mso-hide:screen;text-decoration:none; text-underline:none'> PAGEREF _Toc134877252 /h </span><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-separator'></span></span><![endif]-->13<!--[if gte mso 9]><xml> <w:data>08D0C9EA79F9BACE118C8200AA004BA90B02000000080000000E0000005F0054006F0063003100330034003800370037003200350032000000</w:data> </xml><![endif]--><!--[if supportFields]><span style='color:windowtext; display:none;mso-hide:screen;text-decoration:none;text-underline:none'><span style='mso-element:field-end'></span></span><![endif]-->

<!--[if supportFields]><span lang=EN-US><span style='mso-element:field-end'></span></span><![endif]-->

1 BREW概览

1.1 BREW简介

BREWBinary Runtime Environment for Wireless,即无线二进制运行环境)是QUALCOMM 公司的产品。它以组件(COM)的组织形式封装了底层平台提供给应用开发的服务,屏蔽了底层的实现细节,而提供给应用层统一的API。它所提供的API描述的是Spec而非实现细节,不管今后QUALCOMM的平台技术如何发展,其实现的功能和实现该功能的API规范应该是确定并向后兼容的。

BREW上接受的OEM或其他第三方软件厂商提供的最终软件实体是Module的执行体——Win32模拟环境下是 *.dll,真实机器上是 *.mod,这也体现了BREW中的Binary。另外,也可以在BREW运行时从网络上下载BREW所接受的实体,加入到BREW中来运行。

1.2 BREW中的几个基本概念

BREW中的有AppletExtensionApplet是一个独立运行(从应用开发角度看)的实体,有Applet Context,简记为ACONTEXTExtension通过实现它所定义的接口提供服务给Applet或其它ExtensionExtension不是独立的运行实体,它运行在调用它的Applet(直接或间接地,当前Extension Ext1的某个服务Ext1::srv可能不是由Applet直接调用,但是调用Ext1::srvExtension Ext2归根到底还是可以追溯到某个Applet)的ACONTEXT中。AppletExtension都是被包含在Module里面的,它们之间的关系如一所示。

开发 BREW Extension_第1张图片

图一、BREW中几个概念之间的关系

BREW最终接受的是Module,所以你所提供的AppletExtension必须在某个Module中;另一方面,一个Module里可以有0…nAppletExtension,也可以同时有AppletExtension,还可以两者都没有,不过两者都没有的Module也没有实际意义。Module的属性和它所包含的AppletExtension的信息,以及Dependency关系都描述在MIFModule Information File)文件里,BREW通过该描述文件检索它所需要的信息,并通过相应的Module二进制文件完成相应的操作。

BREW加载AppletExtension时,首先检查包含它的Module是否已经被加载到内存里,如果还没在内存里,BREW要做的工作是先把该Module加载;接着BREW通过该ModuleIMODULE_CreateInstance() 来创建AppletExtension的一个实例,然后才完成AppletExtension的真正加载。

1.3 BREW模拟开发环境

本文所描述的BREW环境和概念都是基于BREW <chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on">3.0.1</chsdate>,采用的程序在下面软件环境中调试通过:

BREW SDK <chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on">3.0.1</chsdate>,包含
API手册
BREW Simulator, MIF Editor, etc.
Header files & some src files

Microsoft Visual studio,包含
Visual studio 6.0
Visual studio 6.0 Service Package 5

Additions
BREW Application Wizard
BREW Addins for vs60

2 开发BREW Extension

有了上面BREW的概念以及开发调试所需的软件环境,下面我们看如何实现一个BREW Extension

BREW中的Extension虽然与Applet是两个概念,但是实现起来却基本相同,不同之处只是在于,Applet必须实现事件处理,而Extension没有这个要求。

2.1 Extension的应用场景

假定下面场景:一个Extension SampleExt 通过 Interface ISampleExt 提供服务给它的调用者 ClientAppClientApp首先通过 ISHELL_CreateInstance() 创建一个ISampleExt的实例,然后调用该接口实例的方法ISAMPLEEXT_xxx() 通过SampleExt提供的该功能,来实现特定的操作。这里只是通过 SampleExt ISAMPLEEXT_JustSayHello() 来演示如何应用ISampleExtISampleExtSampleExt的定义如图二所示。

开发 BREW Extension_第2张图片

图二、ISampleExtSampleExt 的层次结构

ISampleExt继承了IBaseSampleExt实现了ISampleExt。这里不详细介绍BREW中的COM模型,具体信息参看《BREW COM模型实战》。

有了ISampleExt的接口形式,下面看该Interface的典型应用场景。

开发 BREW Extension_第3张图片

图三、SampleExt 的典型应用场景

2.2 文件组成

一个Module里可以有Applet,也可以有Extension,我们参照《BREW Applet 框架》中一个Module实现多个Applet那样来组织这个工程。不同之处是把其中一个Applet换成Extension,也就是在 Extension 这个 Module 里实现 ClientApp SampleExt

ms vs60环境中通过BREW Application Wizard创建一个 Extension 工程,

并把工程的文件组织成图四所示。

开发 BREW Extension_第4张图片

图四、Extension工程中的文件

BREW装载Module里的AppletExtension时,都会通过AEEClsCreateInstance() 函数,完成AppletExtension的创建,我们可以在这个函数里面做些处理,根据不同的AEECLSID,来创建ClientAppSampleExt的实例。

Factory.c文件中实现AEEClsCreateInstance() 函数,根据不同的AEECLSID,调用各自的构造函数来创建相应的实例。

ClientApp.cClient Applet的对IApplet接口的实现。具体来说就是要实现事件处理函数,以及AddRef() Release() 函数,另外还要实现Factory 所引用的构造函数ClientApp_Constructor()

SampleExt.cSampleExt的实现。具体来说就是要实现ISampleExt中定义的方法,以及 Factory 所引用的构造函数SampleExt_Constructor()

ClientApp.h 定义ClientApp类型。

CSampleExt.h 定义接口ISampleExt中的函数,和ISample的各种操作方法的方便店用形式ISAMPLEEXT_xxx(),以及SampleExt类型。

Extension 这个 Module 中要实现一个 Applet 和一个 Extension,所以要把这个Module的描述文件Extension.mif编辑成图五所示。

开发 BREW Extension_第5张图片

图五、编辑Extension.mif

2.3 Module Extension 中的关系

现在Factory SampleExt ClioentApp之间的类图如下:

开发 BREW Extension_第6张图片


图六、SampleExt ClientApp 以及 Factory 之间的关系

图中省略了AEEModGen,我们利用它来实现Module

AEEClsCreateInstance() BREW 通过Module 创建 Module Applet Extension 的入口,这里我们把它定义在 Factory 中,它根据参数 ClsId 的值决定调用 ClientApp 还是 SampleExt Constructor

ClientApp 利用 AEEAppGen 实现Applet,并保留对 ISampleExt 的实例的引用。

2.4 实现Extension

<chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><span style=""><span style=""><span lang="EN-US" style='font-size: 10.5pt; line-height: 173%; font-family: "Courier New";'>2.4.1</span></span></span></chsdate> 类型定义

定义 ISampleExt

ISampleExt 继承 IBaseIBase BREW 里所有 Interface 的基接口。在 ISampleExt中只是加入 JustSayHello() 方法。为了给调用者调用方便,定义操作ISampleExt的方法的三个宏 ISAMPLEEXT_AddRefISAMPLEEXT_Release ISAMPLEEXT_JustSayHello

typedef struct _ISampleExt ISampleExt;

#define INHERIT_ISampleExt(iname) /
INHERIT_IBase(iname); /
void (*JustSayHello)(iname*)

QINTERFACE(ISampleExt)
{
INHERIT_ISampleExt(ISampleExt);
};

/* These Macroes are provided for Client to Use */
#define ISAMPLEEXT_AddRef(p) /
AEEGETPVTBL((p),ISampleExt)->AddRef(p)

#define ISAMPLEEXT_Release(p) /
AEEGETPVTBL((p),ISampleExt)->Release(p)

#define ISAMPLEEXT_JustSayHello(p) /
AEEGETPVTBL((p),ISampleExt)->JustSayHello(p)

代码片断一、定义ISampleExt

定义 SampleExt

对比BREW Applet 框架》中HelloBREW的定义,成员中没了 AEEApplet 这个Applet的缺省各种结构。由于没了AEEApplet,所以SampleExt中必须自己添加指向虚表的指针 pvt和引用计数m_nRefs。指向虚表的指针 pvt 必须在第一个成员位置,因为BREW默认的各种方法的操作都是基于这个指针指向的实现函数的虚表的。引用计数m_nRefs 是为了使这个组件能够被重复利用而采用计数所需设置的。关于BREW中的组件实现技术,参见《BREW COM的实现》。

typedef struct _SampleExt {
// First element of this structure must be pvt
AEEVTBL(ISampleExt) *pvt;

// Reference Count
int m_nRefs;

IDisplay *m_pIDisplay;
IShell *m_pIShell;
IModule *m_pIMod;
} SampleExt;

代码片断二、定义SampleExt

定义 ClientApp

ClientApp的定义参见BREW Applet 框架》中Applet的定义,这里不再赘述。

<chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><span style=""><span style=""><span lang="EN-US" style='font-size: 10.5pt; line-height: 173%; font-family: "Courier New";'>2.4.2 A</span></span></span></chsdate>EEClsCreateInstance() 的实现

函数原型为:

int AEEClsCreateInstance(AEECLSID ClsId, IShell *pIShell, IModule *po, void **ppObj)

函数实现的主体根据不同的AEECLSID,调用 Applet Extension 的构造函数来创建相应的Applet

switch (ClsId)
{
case AEECLSID_CLIEBTAPP:
return ClientApp_Constructor(
ClsId,
pIShell,
po,
(IApplet**)ppObj);

case AEECLSID_SAMPLEEXT:
return SampleExt_Constructor(
ClsId,
pIShell,
po,
(ISampleExt**)ppObj);

default:
return EFAILED;
}

return (EFAILED);

代码片断三、Factory.c AEEClsCreateInstance() 的实现

<chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><span style=""><span style=""><span lang="EN-US" style='font-size: 10.5pt; line-height: 173%; font-family: "Courier New";'>2.4.3</span></span></span></chsdate> 构造函数的实现

ClientApp 的构造函数

如同BREW提供的缺省的 AEEClsCreateInstance() 函数那样,ClientApp 在构造函数 ClientApp_Constructor() 里把事件处理函数ClientApp_HandleEvent() 和程序退出时的清理函数注册到BREW里。

SampleExt 的构造函数

如同BREW提供的缺省的 AEEApplet_New () 函数那样,把SampleExt 的构造函数 SampleExt_Constructor() 实现成下面的形式。

SampleExt *pThis = NULL;
AEEVTBL(ISampleExt) *pFuncs;
int nSize = sizeof (SampleExt) + sizeof (AEEVTBL(ISampleExt));

pThis = (SampleExt*)MALLOC(nSize);
*ppObj = pThis;

if (pThis == NULL)
return ENOMEMORY;

pFuncs = (AEEVTBL(ISampleExt) *)((byte*)pThis + sizeof (SampleExt));
pFuncs->AddRef = SampleExt_AddRef;
pFuncs->Release = SampleExt_Release;
pFuncs->JustSayHello = SampleExt_JustSayHello;

INIT_VTBL(pThis, ISampleExt, *pFuncs);

pThis->m_nRefs = 1;
pThis->m_pIShell = pIShell;
pThis->m_pIMod = pIModule;
pThis->m_pIDisplay = NULL;

ISHELL_CreateInstance(pIShell,
AEECLSID_DISPLAY,
(void **)&pThis->m_pIDisplay);

if (!pThis->m_pIDisplay)
{
// Cleanup
FREE_VTBL(pThis, ISampleExt);
FREE(pThis);
return (EFAILED)
}

ISHELL_AddRef(pThis->m_pIShell);
if (pThis->m_pIMod)
IMODULE_AddRef(pThis->m_pIMod);

return (AEE_SUCCESS);

代码片断四、SampleExt_Constructor() 的实现

这其中牵涉到BREW中的COM模型,这里暂不解释,详情参见《BREW COM模型实战》。

<chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><span style=""><span lang="EN-US" style='font-size: 10.5pt; line-height: 173%; font-family: "Courier New";'>3.2.4</span></span></chsdate> SampleExt IBase 中方法的实现

参照BREW提供的缺省的 AEEAppGen AddRef() Release() 函数那样,把SampleExt 中的 IBase 接口的方法实现成下面的形式。

static uint32 SampleExt_AddRef(ISampleExt *pExt)
{
return ++(((SampleExt *)pExt)->m_nRefs);
}

static uint32 SampleExt_Release(ISampleExt *pExt)
{
IShell * pIShell = NULL;
SampleExt * pme = (SampleExt *)pExt;

if (--pme->m_nRefs)
return (pme->m_nRefs);

if (pme->m_pIDisplay)
IDISPLAY_Release(pme->m_pIDisplay);

IMODULE_Release(pme->m_pIMod);

pIShell = pme->m_pIShell;

// delete this SampleExt object
FREE_VTBL(pme, ISampleExt);
FREE(pme);

ISHELL_Release(pIShell); // Release the Shell

return 0;
}

代码片断五、SampleExt IBase 中方法的实现

<chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><span style=""><span lang="EN-US" style='font-size: 10.5pt; line-height: 173%; font-family: "Courier New";'>3.2.5</span></span></chsdate> JustSayHello() 方法的实现

ISAMPLEEXT_JustSayHello() 是由 SampleExt_JustSayHello() 实现的,只是通过在屏幕上输出“Hello Extension”。

static void SampleExt_JustSayHello(ISampleExt *pExt)
{
AECHAR szText[] = L"Hello Extension";
SampleExt *pThis = (SampleExt *)pExt;

IDISPLAY_DrawText(pThis->m_pIDisplay, // Display instance
AEE_FONT_BOLD, // Use BOLD font
szText, // Text
-1, // -1 = Use full string length
0, // Ignored - IDF_ALIGN_CENTER
0, // Ignored - IDF_ALIGN_MIDDLE
NULL, // No clipping
IDF_ALIGN_CENTER | IDF_ALIGN_MIDDLE);

IDISPLAY_Update(pThis->m_pIDisplay);
}

代码片断六、ISAMPLEEXT_JustSayHello() 方法的实现

<chsdate isrocdate="False" islunardate="False" day="30" month="12" year="1899" w:st="on"><span style=""><span style=""><span lang="EN-US" style='font-size: 10.5pt; line-height: 173%; font-family: "Courier New";'>3.2.6</span></span></span></chsdate> ClinetApp 事件处理

ClientApp 收到 EVT_APP_START 事件时,通过ISHELL_CreateInstance() 创建 ISampleExt 的一个实例,收到 EVT_APP_STOP 事件时,将该实例销毁。

ClientApp Active 状态,点击左软键将通过 JustSayHello 来问候大家。

实现如下:

int result = EFAILED;

switch (eCode)
{
case EVT_APP_START:
result = ISHELL_CreateInstance(pMe->pIShell,
AEECLSID_SAMPLEEXT,
(void**)&pMe->m_pISampleExt);

if (AEE_SUCCESS == result)
return (TRUE);
return (FALSE);

case EVT_APP_STOP:
if (NULL != pMe->m_pISampleExt)
ISAMPLEEXT_Release(pMe->m_pISampleExt);
return (TRUE);

case EVT_KEY:
switch (wParam)
{
case AVK_SOFT1:
if (NULL != pMe->m_pISampleExt)
{
ISAMPLEEXT_JustSayHello(pIExt);
}
break;
...
}
break; // end of EVT_KEY

...

} // switch (eCode)

代码片断七、ClientApp 对事件的处理

2.5 执行序列

ClientApp SampleExt 实现在一个 Module 中。AEEClsCreateInstance() BREW创建Applet Extension的入口,它根据clsId分别调用相应构造函数。在各自的构造函数中,Applet Extension 有机会来初始化自己的数据并注册函数。

ClientApp SampleExt 以及 BREW 的之间的执行过程如图七所示。

开发 BREW Extension_第7张图片

图七、ClientApp SampleExt 的执行过程

启动 ClientApp SampleExt 之前首先要装载它的Module [序列1]
装载完成之后,BREW才通过 IMODULE_CreateInstance() 来创建 ClientApp 的实例,IMODULE_CreateInstance() 通过调用 Factory AEEClsCreateInstance() 来实现 [序列 3 ~ 6 ]
ClientApp 创建并装载完成之后,会收到EVT_APP_START事件,ClientApp收到这个事件之后,用ISHELL_CreateInstance() 创建 ISampleExt 的实例 [序列7 ~ 9]
因为 SampleExt 所在的 Module 已经被转载进内存,不需要再装载,BREW再次通过 IMODULE_CreateInstance() 来创建 SampleExt 的实例。处理同创建 ClientApp 过程一样,只是这里的 ClsId 变为 AEECLSID_SAMPLEEXT,所以执行 SampleExt_Constructor() [序列10 ~ 14]
点击左软键,ClientApp 通过ISAMPLEEXT_JustSayHello() 利用 SampleExt 提供的功能来问候 [序列15 ~ 18]

因为 SampleExt 运行在 ClientApp Applet 上下文(ACONTEXT),所以创建SampleExt的实例和调用它的函数,都不会引起 ClientApp 收到 Suspend 之类的事件。

总结

Extension 的实现同 Applet,它给BREW的扩展提供了很好的机制。

按照QUALCOMM BREW的扩展规约,你可以开发Extension给别人使用,同时也能使用别人开发的Extension。得益于社区的同时,贡献社区。

参考资料及进一步参考

[1] QUALCOMM, BREW API Reference Manual, v<chsdate year="1899" month="12" day="30" islunardate="False" isrocdate="False" w:st="on">3.0.1</chsdate>
[2] BREW Applet框架 http://blog.csdn.net/thl789/archive/2006/05/08/712453.aspx
[3] Ray Rischpater, Writing BREW Extensions
[4] Extension Source Code

关于作者

田海立,硕士,国家系统分析师,中国系统分析员协会专业顾问。

您可以通过 haili.tian(at)csai.cn tianhaili(at)nju.org.cn 与他联系,到 http://blog.csdn.net/thl789/ 看他最新的文章。

版权声明:

本文为作者原创作品,版权归作者所有。
为了学习和研究,可转载本文,但必须与原文的内容和格式保持一致,并给出原文的原始链接!

http://blog.csdn.net/thl789/archive/2006/05/08/713323.aspx

你可能感兴趣的:(brew)