开发 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中几个概念之间的关系

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的定义如图二所示。

图二、ISampleExtSampleExt 的层次结构

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

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

图三、SampleExt 的典型应用场景

2.2 文件组成

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

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

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

图四、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编辑成图五所示。

图五、编辑Extension.mif

2.3 Module Extension 中的关系

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


图六、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 的之间的执行过程如图七所示。

图七、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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值