首页 Brew的思想和系统架构

Brew的思想和系统架构

举报
开通vip

Brew的思想和系统架构浅析BREW的思想和系统架构 关键词: Module 模块。 Applet 小程序,是一类支持基本IApplet接口的小程序,实现某一功能的可执行的应用程序,可以将小程序等同于应用(Application)。 MIF(Module Information File) 模块信息文件,MIF编辑器可以生成此二进制文件,该文件包含此模块支持的一系列类别和Applet程序的信息。 OEM(Original Equipment Manufacturers) 原始设备制造商。 OIL(OEM Interface Layer) ...

Brew的思想和系统架构
浅析BREW的思想和系统架构 关键词: Module 模块。 Applet 小程序,是一类支持基本IApplet接口的小程序,实现某一功能的可执行的应用程序,可以将小程序等同于应用(Application)。 MIF(Module Information File) 模块信息文件,MIF编辑器可以生成此二进制文件,该文件包含此模块支持的一系列类别和Applet程序的信息。 OEM(Original Equipment Manufacturers) 原始设备制造商。 OIL(OEM Interface Layer) OEM接口层,或称OEM层。 BREW AEE(BREW Application Excute Environment) BREW应用执行环境。BREW AEE是支持装载和执行 BREW Applet 程序的环境。 目录: 1 Brew的基本介绍……………………………………………………………………3 1.1 BREW的基本概念和组成…………………………………………………………………………………3 1.2 BREW在无线业务价值链中的地位………………………………………………………………………3 1.2.1 BREW 壮大了产业团队 …………………………………………………………………………3 1.2.2 BREW 为应用开发商的好处 ……………………………………………………………………3 1.2.3 BREW为运营商带来的好处 ……………………………………………………………………4 1.2.4 BREW为手机厂家带来的好处 …………………………………………………………………4 1.2.5 BREW为最终用户带来的好处 …………………………………………………………………4 1.3 BREW的分层体系架构……………………………………………………………………………………4 1.3.1 BREW编程环境 …………………………………………………………………………………5 1.3.2 BREW应用执行环境 ……………………………………………………………………………5 1.3.3 BREW的本地运行环境 …………………………………………………………………………5 2 BREW的元素和功能 ………………………………………………………………………………………………6 2.1 BREW中的基本元素………………………………………………………………………………………6 2.1.1 Class ID …………………………………………………………………………………………6 2.1.2 Interface ………………………………………………………………………………………6 2.1.3 Module……………………………………………………………………………………………6 2.1.4 Applet……………………………………………………………………………………………6 2.1.5 MIF ………………………………………………………………………………………………6 2.2 BREW SDK提供的功能……………………………………………………………………………………6 2.2.1 系统服务 ………………………………………………………………………………………6 2.2.2 用户界面 ………………………………………………………………………………………7 2.2.3 文件系统 ………………………………………………………………………………………7 2.2.4 网络服务 ………………………………………………………………………………………7 2.2.5 多媒体服务 ……………………………………………………………………………………7 2.2.6 其它服务 ………………………………………………………………………………………8 3 BREW接口的声明和实现…………………………………………………………………………………………9 3.1 接口的声明………………………………………………………………………………………………9 3.2 接口的实例化 …………………………………………………………………………………………11 4 模块与应用 ……………………………………………………………………………………………………12 4.1 IModule和IApplet接口………………………………………………………………………………12 4.1.1 IModule接口 …………………………………………………………………………………12 4.1.2 IApplet接口 …………………………………………………………………………………12 4.2 模块和应用的加载及运行……………………………………………………………………………12 4.2.1 模块的加载过程………………………………………………………………………………12 4.2.2 应用的创建……………………………………………………………………………………14 4.2.3 应用的运行……………………………………………………………………………………16 5 BREW的初始化和消息处理………………………………………………………………………………………17 5.1 初始化BREW的运行环境………………………………………………………………………………17 5.2 BREW消息的处理 流程 快递问题件怎么处理流程河南自建厂房流程下载关于规范招聘需求审批流程制作流程表下载邮件下载流程设计 …………………………………………………………………………………17 1​ BREW的基本介绍 1.1 BREW的基本概念和组成 BREW(Binary Runtime Environment for Wireless)是高通公司推出的无线终端二进制运行环境的简称,它是无线终端应用程序的运行平台,是专为无线设备设计的开放 标准 excel标准偏差excel标准偏差函数exl标准差函数国标检验抽样标准表免费下载红头文件格式标准下载 的瘦应用环境。BREW提供了一个开放的接口,按照这个接口开发的应用程序可以在它之上执行。 BINARY:应用和API是二进制代码,非解释性语言。 RUNTIME:应用和扩展类可在手机运行过程中动态加载与运行。 ENVIRONMENT:具有丰富的API功能接口,同时提供应用的下载、运行与管理服务平台。 WIRELESS:应用可以充分利用平台提供的底层无线业务;应用可通过空中下载。 BREW主要由手机平台技术与分发系统两大部分组成的,手机平台技术部分是对手机厂家开放,部分对应用开发商开放。 手机平台技术包括: BREW Porting Kit:供手机厂家进行BREW平台的移植。 Brew Porting Evaluation Kit:供手机厂家进行BREW平台移植的测试与优化。 BREW Tools:提供用于开发与系统调试的各种工具。 BREW SDK:提供API供开发商在BREW手机平台上开发各种BREW应用。 BREW AppMgr:BREW运行环境的应用管理器,包括软件超市,应用设置等功能,配合BREW运行环境 管理应用的加载,运行与释放。 BREW UI Widgets:新的UI编程软件包。 API One PortingKit:新的UI One编程技术,供手机厂家进行UIOne技术移植。 UI One SDK:新的UI One编程技术的可视化开发。 分发系统的全称叫 BREW Distribution System,用于管理应用的上载,数字签名,分发,商用下载,与计费等。 1.2 BREW在无线业务价值链中的地位 无线增值业务价值链上的四个节点是运营商、设备制造商、应用开发商和消费者。BREW提供了一个贯穿整个无线增值业务价值链各个环节的开放的端到端解决 方案 气瓶 现场处置方案 .pdf气瓶 现场处置方案 .doc见习基地管理方案.doc关于群访事件的化解方案建筑工地扬尘治理专项方案下载 ,开启了进入这一快速增长的广大市场的大门。BREW使得消费者最终将拥有对他们无线设备上应用程序的选择和控制权,这意味着推动无线数据市场前进的将是市场的力量,从而最终使所有市场参与者获益。 1.2.1 BREW壮大了产业团队 BREW,即QUALCOMM推出的无线二进制运行环境。借助于这个平台,许多无线应用可以简易快捷地开发,原本几乎与无线市场无缘搭界的第三方开发商从此可以涉足这一新生市场。采用BREW技术的CDMA手机,可以无线下载或预装各种应用(或称小程序)。BREW应用的开发是开放的、面向对象的,它抛弃了面向过程的传统手机开发模式,它将以前从不与移动终端打交道的第三方纳入了整个产业链,壮大了整个产业团队,培育一个新的应用开发市场. 它提供一个高效、低成本、可扩展和熟悉的应用程序执行环境(AEE),着重开发可无缝植入任何实际手持设备的应用程序。BREW提供了一套应用程序接口(API),制造商和开发人员可以随时对运行环境进行扩展,提供应用程序需要的各种附加性能模块,如“无线互联网发射平台”中包含的多媒体、多种连接方式、位置服务、用户界面、网络等功能套件。BREW技术几乎可以将手机的所有软件功能抽象成应用,例如电话簿、短消息、无线浏览、振铃、多媒体播放、摄像、日历、闹钟、游戏等,甚至最基本的打电话功能都可以归纳为应用进行开发。这些应用开发既可以由手机生产厂商自己进行,也可以交给第三方--CP(内容供应商)来进行。 1.2.2 BREW为应用开发商的好处 BREW SDK为应用开发人员提供了一个统一的技术开发平台: 无需了解更多手机嵌入式系统的底层实现技术,通过BREW SDK的接口API就可以开发出各种复杂优秀的应用与服务。 可以在熟悉的VC或VS.net开发环境中开发和调试应用。 可以充分的使用底层芯片组的强大功能。 不需要应用本身管理复杂的电话功能。 BREW 为BREW应用提供了一个跨越不同手机设备和型号的通用运行环境,减少了为每种不同设备重复编写应用程序的工作量。 开发商的应用可以通过BREW的发布系统被放到下载服务器上直接面向广大消费者,避免了所有的商品销售中间环节。这样大大减少了应用的市场推广费用 通过BREW的发布系统,应用开发商将从用户购买中自动获得收益。 1.2.3 BREW为运营商带来的好处 BREW应用能有效帮助运营商开展差异化竞争,通过快速推出各种无线数据应用、内容和服务,能够更好的适应快速变化和激烈竞争的市场。 可以充分利用CP/SP在应用推广与服务方面的经验 BREW为运营商带来了新的盈利契机和商业模式。 应用下载的信息费分成。 应用下载的流量费。 在线BREW应用使用流量费。 优质的应用服务帮助运营商增加用户数,减少客户流失。 1.2.4 BREW为手机厂家带来的好处 BREW将帮助手机厂家极大降低手机本身软件开发工作量,加快产品的开发周期。 BREW能够显著降低手机软件移植到新的手机型号所需的大量集成工作,培训工作以及开发周期。 BREW丰富多彩的应用为手机增加了更多的销售亮点,有助于手机厂家提高手机销量。 BREW对系统资源的需求非常小,能够显著降低手机推出新增值业务的成本。 BREW技术的开放性和可扩展性将帮助手机厂家顺利过渡到3G时代 1.2.5 BREW为最终用户带来的好处 BREW通过软件超市为用户提供了一个可以随时随地进行应用下载的渠道。 方便灵活的购买方式便于满足用户各种不同的消费需求。 BREW丰富多彩的应用基本上可以覆盖用户各种不同的喜好与需求。 用户通过软件超市来下载各种应用,就可以大大扩展手机本身的功能,实现所谓的个性化手机 1.3 BREW的分层体系架构 BREW不是一种操作系统,也不是一种开发语言,本质上来说BREW是一种中间件。BREW位于操作系统(以及本地软件)与上层应用之间,BREW在手机上的实现需要操作系统服务的支持,从理论上来说,BREW可以在任何操作系统上被支持起来。BREW定义了一套标准的接口(环境),这套标准的接口(环境)是面向上层的,面向开发的,而这套接口(或者环境)的实现则是调用了的操作系统(以及本地软件)的服务。这样,BREW屏蔽了底层的差异性和具体实现,对上提供标准的接口。 对于应用开发者来说,他们无需考虑具体手机,只需要利用BREW提供的标准接口(环境)就可以开发可移植的应用。通过BREW可以使得应用的开发变得可扩展,灵活和“标准”。这种可移植性的本质是因为,对于开发者所呈现的“共性”是通过OIL层实现的“个性”来呈现的,并且通过中间件这样一种模式,屏蔽了这种共性和个性之间的联系,使得使用和实现分离,达到了可移植性。由于BREW平台的通用性,软件开发商在BREW环境中一次写就的应用程序,可以无需进行任何改变,即可适用所有支持BREW的各种档次终端中。BREW的软件开发包(SDK)使开发商在他们熟悉的基于Windows的环境下工作,创造并测试开发的应用。 BREW的这种通用性,可移植性,可扩展性是通过它的分层结构来实现的。BREW提供了一个开发无线应用程序的编程环境,以BREW API和BREW SDK的方式提供;一个运行环境,或称为BREW应用执行环境,即BREW AEE,这是保证开发的应用可以在多种设备中以一致方式来运行;同时,第三方软件开发商开发的软件通过BREW集成到具体OEM产商所提供的特定的本地执行环境中,使得第三方软件可以获取操作系统及本地软件的服务,从而使在模拟器上开发的应用在具体的手机上得到实现。 1.3.1 BREW编程环境 BREW的API和SDK极大地简化了用C、C++和其他语言开发无线应用。 BREW的API以一组接口类的方式组织起来,每个接口类提供某一特定服务的一组函数。有些服务,如事件通知、菜单和对话等图形用户界面和互联网连接是现代编程环境中标准配置,有些接口类则显示了无线环境中的一些特性,如地址簿、振铃库和定位信息等。所以BREW API使开发商无需了解设备的内部机理也能从事无线应用的开发。接口类采用COM组件的方式进行设计,同时采用了类似Windows风格的事件驱动与消息处理机制,事件处理、菜单、对话、资源、编辑、基于文件的长期储存和 记录 混凝土 养护记录下载土方回填监理旁站记录免费下载集备记录下载集备记录下载集备记录下载 导向型的数据库是BREW中标准的概念,熟悉事件驱动图形界面环境的开发商将会发现BREW API好学易用。而且,基于Windows的模拟环境使那些对Windows应用程序编写驾轻就熟的程序员可以特别轻松地用Visual C++去开发BREW应用。 BREW Emulator使开发人员可以测试无线应用在一系列仿真设备Windows环境下运行的状况,这样就免去了在真实设备中的测试。 由于BREW API可适用于多种设备,利用BREW API编写的程序可以轻松地从一个无线设备移植到其他无线设备中。所以开发商编程一次,就可运行在多种设备中。虽然不同设备由于显示尺寸不同可能要对程序进行微调,但大多种这种细微的调整可以在BREW Emulator中轻易地测试出来,这同以往开发商若想他们开发的程序在多种无线设备上运行必须繁复地将代码逐一移植,而且必须熟知各种设备所在运行环境的所有细节相比轻松许多。 BREW API可以支持扩展,设备厂商、运营商和开发商可以编写插件类来拓展BREW的功能,这些插件类可能包括支持其他多媒体格式的播放器和浏览器,也包括Java虚拟机。 1.3.2 BREW应用执行环境 BREW 应用执行环境即BREW AEE,它是保证开发的应用可以在多种设备中以一致方式运行的基础。BREW的应用执行环境(AEE)是一个精巧的软件接口层,OEM厂商将它集成在各自的软件中,以支持BREW API和编程环境。 BREW应用运行环境(AEE)为应用提供了一个全功能的实时运行环境用于支持BREW API和应用的运行调度。AEE通过BREW API接口类的方式为BREW应用提供范围广泛的底层功能调用。AEE管理应用的执行,包括应用的启动、退出、中断与恢复。AEE还保证运行环境与手机的核心功能的协调工作,确保应用在运行过程中及时响应用户和一些紧急事件。 1.3.3 BREW的本地运行环境 BREW的本地运行环境包括操作系统,OIL层,设备驱动及服务层提供的功能,开发者通过BREW API以及AEE层实现将BREW应用集成到具体的设备上。BREW的不同层面向不同的用户,OIL层是面向手机OEM厂商的,是用来进行BREW 移植的,而对于BREW上层开发者而言,本质上只需要,也只能运用编程环境中的API以及一些AEE层的辅助函数. AEE层虽然定义并实现了一套标准的接口,但是在AEE层的这些接口函数的具体实现中最终会调用OIL层的函数,因为BREW类似于一个中间件,与底层平台无关,但是这种无关性是通过OEM厂商的"相关"的操作来实现的.即BREW在AEE层定义了标准的接口行为,而在OIL层由厂商通过各自不同的方式来实现同样的外在表现. 一旦OIL层的这些函数厂商都实现了(平台相关性),那么标准的BREW AEE层就可以顺利调用这些实现的函数来达到规定的行为了(表现出平台无关性). 2​ BREW的元素和功能 2.1 BREW中的基本元素 2.1.1 Class ID Class ID在BREW中是一个非常重要的概念。每一个Applet和BREW接口类都有一个唯一的32位二进制数值Class ID所标识。SHELL启动一个Applet或者给一个Applet发送消息,都需要指定对应的Applet的Class ID,而为了使小程序可以使用某个接口类的函数,小程序也必须通过对应的接口类的Class ID创建接口。BREW的头文件AEEClassIDs.h为所有的BREW API类提供了助记符。 2.1.2 Interface Interface即接口是继承自IBase的类,是实现一组相近功能的函数的集合,提供一类特定的服务。模块或者小程序通过对应的Class ID访问这一组函数。 2.1.3 Module Module即模块是IModule类的特例,是一个或多个小程序(IApplet)和接口类的集合。模块以.mod格式存在终端的文件系统中,.mod文件是在编译过程中生成的。 2.1.4 Applet Applet即BREW小程序是IApplet的特例,每个IApplet类都有对应的ClassID。SHELL通过指定对应的Applet的Class ID来启动一个Applet或者给一个Applet发送消息。 2.1.5 MIF MIF即模块信息文件保存模块中每个小程序的重要信息。对于每个小程序,MIF包含小程序的Class ID以及一个到多个对应的图标,用来标识用于执行小程序菜单中相应的小程序。MIF中还有小程序所依赖的非小程序类的ClassID以及其他信息。如果忽略了MIF文件中正确权限的选择,创建小程序有可能失败。 2.2 BREW SDK提供的功能 2.2.1 系统服务 应用基础 IApplet IModule IBase IQuery 内存管理 IRamCache IPeek IHeap IClipBoard 许可和购买信息 ILicense Shell 服务 应用程序管理 资源文件的管理 设备和应用程序配置信息 Notification Alarms Timers 对话框,message boxes和prompts 其他功能 (如 Beep) 2.2.2 用户界面 基本显示(IDisplay) DrawText MeasureText text metrics Rectangle operations 字体 IFont UI 组件 对话框(Idialog) 静态文本框(Istatic) 菜单(ImenuCtl) 输入文本框(ItextCtl) 时间的显示 ITimeCtl IDateCtl 2.2.3 文件系统 文件系统访问 目录的访问 文件的访问 数据库服务 Open, read, write, etc. Variable records Variable fields Access to device’s address book and ringer databases 地址簿服务 地址簿访问(IAddrBook) 记录的访问(IAddrRec) 2.2.4 网络服务 底层Socket服务 DNS的获取 网络子系统的获取 异步通信 内容的提取 内容的处理 基于HTTP的服务 Web连接的建立与维护 WEB选项的设定 Web响应的获得 内容的提取 内容的处理 内容的显示 2.2.5 多媒体服务 Graphics(2D) Polygon draw/fill Shapes Sound Player/Media MP3 MIDI/CMX PureVoice(voice memos) Image support Pictures Animation 2.2.6 其它服务 安全服务 Cipher RSA SSL MD5 电信服务 电话与短消息(ITAPI) 语音处理(IVocoder) 蓝牙 LBS 服务 GPSone 定位(IPosDet) 帮助函数 实现了标准的ANSI C 库函数 3​ BREW接口的声明和实现 3.1 接口的声明 接口本质就是一个定义好的“函数指针集”,通过该函数指针集实现一个抽象的,虚拟的,通用的接口层,可以在创建该接口时动态地实例化这些函数指针。下面以以QINTERFACE声明的IImageCtl接口为例分析接口的声明过程。接口的声明过程中使用了几个宏,如下: #define VTBL(iname) iname##Vtbl #define DECLARE_IBASE(iname) \ uint32 (*AddRef) (iname*);\ uint32 (*Release) (iname*); #define DECLARE_VTBL(iname) iname vt##iname; #define GET_PVTBL(p,iname) ((iname*)p)->pvt #define OBJECT(n) \ typedef struct n n;\ struct n 如下是AEEImageCtl.h中IImageCtl的声明: typedef struct _IImageCtl IImageCtl; QINTERFACE(IImageCtl) { DECLARE_IBASE(IImageCtl) DECLARE_ICONTROL(IImageCtl) void (*SetImage)(IImageCtl * po,IImage * pi); void (*SetRedraw)(IImageCtl * po, PFNNOTIFY pfn, void * pUser); }; 在AEE.h中我们可以看到QINTERFACE宏的原型: #define QINTERFACE(iname) struct _##iname {\ struct VTBL(iname) *pvt;\ };\ typedef struct VTBL(iname) VTBL(iname);\ struct VTBL(iname) 展开IImageCtl原型中的宏可以看到(DECLARE_ICONTROL宏的原型在AEE.h中,该宏定义了一些控件接口所共有的函数指针,这里限于篇幅就不展开了): typedef struct _IImageCtl IImageCtl; struct _IImageCtl { struct IImageCtlVtbl *pvt; }; typedef struct IImageCtlVtbl IImageCtlVtbl; struct IImageCtlVtbl { uint32 (*AddRef) (iname*); uint32 (*Release) (iname*); DECLARE_ICONTROL(IImageCtl) void (*SetImage)(IImageCtl * po,IImage * pi); void (*SetRedraw)(IImageCtl * po, PFNNOTIFY pfn, void * pUser); }; 由上可以看到接口的声明中作了几件事: 1.​ 声明了一个_IImageCtl结构体,该结构体只有一个成员变量,是指向IImageCtlVtbl 结构体的一个指针,这个指针其实就是接口的关键,他指向的就是一张虚函数表,当这个指向虚函数表的指针被实例化以后,就可以通过这个它来调用接口的实例化函数。 2. 定义了一个结构体类型IImageCtlVtbl,IImageCtlVtbl结构体所声明的是一张虚函数表,它的每一 个成员变量都是一个函数指针,这些函数指针所指向就是接口实现函数,对接口的访问就是通过这个指针实现的。 在IImageCtl接口声明之后可以看到一系列的宏声明,这些宏就是应用所调用的抽象接口,这些宏封装了对IImageCtl接口访问的细节,这样应用不需要关心IImageCtl是如何实现的,也不需要关心如何才能访问IImageCtl所提供的接口,更不需要关心所提供的IImageCtl的内部结构。应用只需要使用它所对应的Class ID创建一个IImageCtl实例,然后使用这些宏就能访问想要的接口了。下面来分析一下这个宏是如何与我们上面声明的虚函数表对应起来的: #define IIMAGECTL_SetRedraw(p,pfn,pu) GET_PVTBL(p,IImageCtl)->SetRedraw(p,pfn,pu) 展开GET_PVTBL宏我们可以看到: #define IIMAGECTL_SetRedraw(p,pfn,pu) ((IImageCtl *)p)->pvt->SetRedraw(p,pfn,pu) 很显然这个宏只是帮助我们取得了IImageCtl(即_IImageCtl)中声明的指向虚函数表的指针,然后再通过这个指针访问相应的接口函数。 接口只是声明了一系列的函数指针,我们需要声明一个与接口相对应的结构体帮助我们实现接口的功能,对IImageCtl来说这个结构体就是ImageCtl。当我们ISHELL_CreateInstance创建一个IImageCtl接口类时,分配的内存块的大小是以ImageCtl结构体的大小来分配的,创建成功后得到的也是一个指向ImageCtl的指针,只不过我们访问接口过程中进行了强制类型转换。还以IImageCtl为例, AEEImageCtl.c声明了一个与IImageCtl相对应的结构体: OBJECT(ImageCtl) { DECLARE_VTBL(IImageCtl) uint32 m_nRefs; IShell * m_pShell; IImage * m_pImage; IDisplay * m_pDisplay; … … }; 展开这个结构体中的宏,可以看到: typedef struct ImageCtl ImageCtl; struct ImageCtl { IImageCtl vtIImageCtl uint32 m_nRefs; IShell * m_pShell; IImage * m_pImage; IDisplay * m_pDisplay; … … } 由上可知,ImageCtl结构体中声明了一个IImageCtl类型的成员变量vtIImageCtl,vtIImageCtl中的唯一成员变量就是对应的接口类虚函数表的指针,注意这里并不需要也不能把它声明为一个指针,同时这个成员变量必须是第一个被声明的成员变量,这样我们使用宏访问接口过程进行的强制类型转换才是正确的。另外,ImageCtl结构体中还声明了许多成员变量,这些东西对于接口的应用来说都是透明的,它们并不需要关心这些成员变量。 注意:BREW中还有一种声明接口的 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 ,它使用的是AEEINTERFACE来声明接口,这二者之间的区别主要是:AEEINTERFACE声明接口时并未声明只有一个指向该接口类函数表的指针的成员变量的结构体类型,取而代之,它在该接口对应的结构体中直接声明了一个指向该接口虚函数表的指针,这两种声明接口的方式本质上没什么区别,这里就不做详细分析了。 3.2接口的实例化 以上分析了接口的声明过程,声明完一个接口之后,应用并不能立即使用这个接口提供的函数,因为它还没实例化。OEMModTable.c中函数OEMMod_GetStaticClassLists中变量aascBREW(注意这个局部变量声明为Static Const)定义了一张static class表,OEMModTableExt.c中全局变量gOEMStaticClassList也定义了一张static class表,这两张表列出了6280移植的BREW平台中所有接口的实例化入口函数.当应用通过ISHELL_CreateInstance创建一个接口时,BREW根据请求创建的接口的Class ID找到对应的实例化入口函数来创建接口类. 还以IImageCtl为例介绍一下接口的实例化过程,IImageCtl对应的Class ID为AEECLSID_IMAGECTL在gControlClassList表中可以找到该接口的实例化函数为ImageCtl_New。 ImageCtl_New在实例化接口过程中主要完成3件事情: 1 调用AEE_NewClass为IImageCtl分配了一块sizeof(ImageCtl)大小的内存。 2 同时在AEE_NewClass调用过程中也将IImageCtl的虚函数表指针实例化为gViewerFuncs,在实例化虚函数表的同时,虚函数表中的每个函数指针都被赋予gViewerFuncs所定义的相应的实际函数的地址,这样应用访问接口实际上访问的是gViewerFuncs中所定义的这些函数。 3 初始化ImageCtl的数据成员。 4 将创建的ImageCtl指针传回给调用者。 4​ 模块与应用 4.1 IModule和IApplet接口 IModule 和 IApplet 与所有其它接口的根本区别在于,它们实现的是应用程序提供的服务,而非应用程序使用的服务。它们为外壳提供一种加载、管理事件和向应用程序传递事件的机制。BREW SDK提供了 IModule 和 IApplet 接口的默认实现。 4.1.1 IModule接口 在BREW中,Module是基本的执行单位,一个Module可以包含一个或多个Applet,或者多个extension class。按照Module是处于code space(即OEM出厂时已经将module编译进image中了)还是通过下载方式(无线下载或者数据线下载)存于文件系统可以分为static和dynamic,主要包括:dynamic module(applet),static module(applet)和dynamic extension class(module)。BREW Module的基础是 IShell加载Module时所使用的机制,每个静态和动态模块都导出一个入口点用来加载模块,BREW 调用该加载函数创建IModule实例,然后通过IModule请求启动Module中指定的应用。 IModule 仅提供两个功能函数。 第一个也是最关键的函数IModule_CreateInstance允许 BREW 请求创建模块中指定的应用实例。第二个函数IModule_FreeResources允许 BREW 请求模块释放任何多余的系统资源。BREW提供了这两个函数的实现默认实现(AEEModGen.c):AEEMod_FreeResources,AEEMod_CreateInstance。IModule对应的结构体为AEEMod(AEEModGen.h),该结构体中声明了两个函数指针类型的成员变量pfnModCrInst,pfnModFreeData,pfnModCrInst是静态Module指定的创建应用的入口点,pfnModFreeData是静态Module用于释放资源的函数,如果没有资源需要释放,可以将该指针指向空。 4.1.2 IApplet接口 IApplet 接口可以实现小程序提供的服务。IApplet 接口的主要服务是为外壳提供一种将事件传递给小程序的机制,每个Applet其实都是IApplet的一个实例。IAPPLET只提供了一个也是最重要的功能函数的函数就是IApplet_HandleEvent。BREW提供了这个函数的默认实现(AEEAppGen.c):AEEApplet_HandleEvent。AEEApplet_HandleEvent只是调用了pAppHandleEvent所指向的函数,AEEAPPLE是IApplet所对应的结构体,而pAppHandleEvent正是 AEEAPPLET的一个成员变量,它是一个函数指针,指向的是每个Applet自身的事件处理函数,它在Module加载过程中调用AEEAPPLET_New的时候被初始化的,这样通过这个指针BREW就能调用具体应用的事件处理函数来处理事件。 4.2模块及应用的加载和运行 由于高通没有公开完整的Module和Applet的加载过程,以下结合文档和自己的实践经验分析一下模块及应用的加载和运行过程。 4.2.1 模块的加载过程 首先,手机开机过程中调用AEE_init进行BREW环境初始化时,通过检索文件系统中的各个MIF文件来获得各个dynamic module的信息,而对于static module,由于MIF文件已经编译为.mod的文件了,所以过程有所不同,对于每个static module必须提供一个XXX_getmodinfo()函数,通过这个函数就可以获得Module的信息,通过这一步检索过程建立了一张Module List,这样当加载Module时通过检索可以找到相应的Module的信息。需要注意的是,在这一步过程中,对于dynamic module,Module的载入函数是通用AEEMod_Load实现的,所以应用无需再提供自己的Load函数,而static module必须提供自己的XXX_Load 函数,当外壳要求加载模块时,调用这个函数完成加载工作。 然后,当用户向外壳请求启动某个应用时(调用ISHELL_StartApplet),通过检索初始化过程中建立的Module List取得Module的加载函数,对于dynamic module,加载是通过通用函数AEEMod_Load实现的,而对于static module,则是调用它指定了的加载函数,这二者其实都是调用AEEStaticMod_New完成加载过程的,但是二者之间有一个关键的区别在于对于dynamic module它传递给AEEStaticMod_New的后面两个参数为空(参见AEEModGen.c中的AEEMod_Load实现): AEEStaticMod_New(sizeof(AEEMod),pIShell,ph,ppMod,NULL,NULL); 这两个参数是传递给pfnModCrInst与pfnModFreeData的,pfnModCrInst是静态Module指定的创建应用的入口点,pfnModFreeData是静态Module用于释放资源的函数。当创建Applet时,Module会根据pfnModCrInst来判断调用哪个函数进行创建。参考AEEStaticMod_New(AEEModGen.c)的实现我们可以看到模块加载的过程: int AEEStaticMod_New(int16 nSize, IShell *pIShell, void *ph, IModule **ppMod,                     PFNMODCREATEINST pfnMC,PFNFREEMODDATA pfnMF) { AEEMod *pMe = NULL; VTBL(IModule) *modFuncs;   … …   //Allocate memory for the AEEMod object   if (nSize < sizeof(AEEMod)) {      nSize += sizeof(AEEMod);   }   if (NULL == (pMe = (AEEMod *)MALLOC(nSize + sizeof(IModuleVtbl)))) {      return ENOMEMORY;   }      // Allocate the vtbl and initialize it. Note that the modules and apps   // must not have any static data. Hence, we need to allocate the vtbl as   // well.   modFuncs = (IModuleVtbl *)((byte *)pMe + nSize);   // Initialize individual entries in the VTBL   modFuncs->AddRef         = AEEMod_AddRef;   modFuncs->Release        = AEEMod_Release;   modFuncs->CreateInstance = AEEMod_CreateInstance;   modFuncs->FreeResources  = AEEMod_FreeResources;   // initialize the vtable   INIT_VTBL(pMe, IModule, *modFuncs);   // initialize the data members   // Store address of Module's CreateInstance function   pMe->pfnModCrInst = pfnMC;   // Store Address of Module's FreeData function   pMe->pfnModFreeData = pfnMF; … …    // Set the pointer in the parameter   *ppMod = (IModule*)pMe;   return SUCCESS; } 1 为Module分配内存。 2 实例化Module的虚函数表。 3 初始化成员变量,特别注意pfnModCrInst和pfnModFreeData。 4 返回创建的Module。 4.2.2 应用的创建 外壳通过模块的加载函数获得了一个IModule实例,接下来通过调用IModule_CreateInstance创建应用。在模块的加载过程中,IModule_CreateInstance已经被指向了AEEMod_CreateInstance: modFuncs->CreateInstance = AEEMod_CreateInstance; 所以调用IModule_CreateInstance其实调用的是AEEMod_CreateInstance,来看一下它的实现(AEEModGen.c): static int AEEMod_CreateInstance(IModule *pIModule,IShell *pIShell,                                 AEECLSID ClsId,void **ppObj) {   AEEMod    *pme = (AEEMod *)pIModule;   int        nErr = 0;   // For a dynamic module, they must supply the AEEClsCreateInstance()   //   function. Hence, invoke it. For a static app, they will have   //   registered the create Instance function. Invoke it.   if (pme->pfnModCrInst) {      nErr = pme->pfnModCrInst(ClsId, pIShell, pIModule, ppObj); #if !defined(AEE_STATIC)   } else {      nErr = AEEClsCreateInstance(ClsId, pIShell, pIModule, ppObj); #endif   }   return nErr; } 对于dynamic module,由于pme->pfnModCrInst为NULL,所以调用通用的创建函数AEEClsCreateInstance(ClsId, pIShell, pIModule, ppObj)来进行创建。而对于static module,因为指定了自身的CreateInstance函数,所以pme->pfnModCrInst不为NULL,从而执行该Module自身的CreateInstance函数。不管是 AEEClsCreateInstance还是pme->pfnModCrInst其实创建应用的过程都是类似的,通过AEEApplet_New(除extension class外通常都是调用该函数)来最终创建Applet,来看一下AEEApplet_New(AEEAppGen.c)创建应用的过程: boolean AEEApplet_New(int16 nIn, AEECLSID clsID, IShell * pIShell, IModule * pIModule, IApplet **ppobj, AEEHANDLER pAppHandleEvent, PFNFREEAPPDATA pFreeAppData) { AEEApplet * pme = NULL; VTBL(IApplet) * appFuncs; … … // Create an Applet object if (NULL == (pme = (AEEApplet*)MALLOC(nSize + sizeof(IAppletVtbl)))) return FALSE; appFuncs = (IAppletVtbl *)((byte *)pme + nSize); //Initialize the individual entries in the VTBL appFuncs->AddRef = AEEApplet_AddRef; appFuncs->Release = AEEApplet_Release; appFuncs->HandleEvent = AEEApplet_HandleEvent; INIT_VTBL(pme, IApplet, *appFuncs); // Initialize the VTBL //Initialize the data members pme->m_nRefs = 1; pme->m_pIShell = pIShell; pme->m_pIModule = pIModule; pme->m_pIDisplay = NULL; pme->clsID = clsID; //Store the function pointers to APP's HandleEvent and FreeAppData functions pme->pAppHandleEvent = pAppHandleEvent; pme->pFreeAppData = pFreeAppData; … … *ppobj = (IApplet*)pme; return TRUE; } 1 为Applet分配内存。 2 实例化Applet的虚函数表。 3 初始化成员变量,特别注意pAppHandleEvent和pFreeAppData。 4 返回创建的Applet。 4.2.3 应用的运行 外壳通过模块的应用创建函数获得了一个IApplet实例,接下来就通过调用IApplet_HandleEvent给应用发送一个EVT_APP_START,通知应用开始运行。在应用的创建过程中,IApplet_HandleEvent已经被指向了AEEApplet_HandleEvent: appFuncs->HandleEvent = AEEApplet_HandleEvent; 所以调用IApplet_HandleEvent其实调用的是AEEApplet_HandleEvent,来看一下它的实现(AEEAppGen.c): boolean AEEApplet_HandleEvent(IApplet * po, AEEEvent evt, uint16 wParam, uint32 dwParam) { return ((AEEApplet *)po)->pAppHandleEvent(po, evt,wParam,dwParam); } AEEApplet_HandleEvent只是调用了pAppHandleEvent所指向的函数,pAppHandleEvent在应用创建时被初始化为每个应用所指定的事件处理函数: pme->pAppHandleEvent = pAppHandleEvent; 这样通过这个指针BREW将EVT_APP_START事件传递给应用告诉它开始运行。下图是动态模块和应用的加载及运行过程: 5​ BREW的初始化和消息处理 5.1​ 初始化BREW的运行环境 BREW位于操作系统(以及本地软件)与上层应用之间,BREW在手机上的实现需要操作系统提供的服务,需要运行在Task的上下文环境的,在6280平台上,这个操作系统就式REX,而BREW则运行在REX的UI TASK中。下面看一下UI TASK的启动函数ui_task的核心代码: void ui_task (dword dummy) { rex_sigs_type waitMask; /* hold signals */ … … ui_init(); /* initialize task. */ … … waitMask |= CoreApp_Getsigs(); … … /* Wait on REX signals, repeat forever */ for( ;; ) { rex_sigs_type sigs; /* hold signals */ … … sigs = rex_wait(waitMask); … … /* Process the signals */ HandleSignals( sigs ); } } ui_task启动时调用ui_init()(ui_base.c)进行了一系列的初始化,其中CoreTask_init()(Core_ui.c)调用了AEE_Init对BREW进行了初始化。 5.2​ BREW消息的处理流程 BREW运行在UI TASK中,其消息的接收也是通过UI TASK转发的,BREW主要关心UI TASK的AEE_APP_SIG, TASK_STOP_SIG, UI_RUIM_SIG等信号。当UI TASK收到AEE_APP_SIG时,首先交由BREW来处理,BREW则调用AEE_Dispatch将消息分发给应用。AEE_Dispatch会检查BREW事件队列中的所有事件,一一分发(此时就会调用IApplet_HandleEvent将事件发给APP Handleevent),同时ISHELL_Resume注册的Callback被放到BREW Callback队列中,BREW在这个过程中也会对这个队列中的Callback函数进行一一处理。如当用户按一个键后,UI Task会首先收到UI_KEY_SIG并首先调用CoreAppHandleSignals(HandleSignals函数中)进行处理,CoreAppHandleSignals判断收到的是按键事件,则调用handle_keys进行处理,handle_keys中调用AEE_Event将该按键事件转换为BREW的按键事件,同时将按键值转为BREW虚拟的键值码(AVK_XXX)放入BREW的事件队列中,并设置Ui Task 的信号AEE_APP_SIG.这
本文档为【Brew的思想和系统架构】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_949959
暂无简介~
格式:doc
大小:136KB
软件:Word
页数:0
分类:互联网
上传时间:2011-05-18
浏览量:23