[深入分析BREW机制]:Mod相关概念解析

来源:互联网 发布:web压力测试软件 编辑:程序博客网 时间:2024/06/05 00:26

 BREW MOD相关概念解析
 目录
 1、Mod与Applet、接口的关系
 2、Mod的唯一标识
 3、Applet、接口的唯一标识
 4、Mod的实体组成
 5、Mod的加载和启动
  5.1 加载Mod
  5.2 启动Mod
 6、在simulator中运行动态Mod

1、Mod与Applet、接口的关系
本文之前谈到的都是Applet和接口,实际上BREW的运行单元是Mod,而Applet、接口只是Mod内部的概念,你也可以简单地理解成:Mod是容器,而Applet、接口是容器里的元素。一个Mod里可以放置任意个applet和接口。或者说Mod是Applet和接口的载体。
在启动一个applet或接口时,BREW只启动到Mod为止,接下来启动哪个applet或接口由Mod来决定。

2、Mod的唯一标识
Mod的唯一标识是mif文件,mif全名为mod information file,即mod信息文件,里面记录了mod的所有可描述性信息,如这个mod里有几个applet,有几个brew扩展接口,每个applet、brew扩展接口的clisid和名字,applet的图标等等。
mif文件的文件名就是这个mod的名字,没有任何可选余地,如,a.mif代表了一个mod,mod的名字便是a,又如,一个mod的名字叫b,那么它的唯一标识就是b.mif。

3、Applet、接口的唯一标识
Applet、接口的唯一标识就是ClsID,每一个applet、BREW扩展接口在商业运作之前都必须申请一个合法的ClsID,在使用模拟器进行开发时,可以使用临时的ClsID,由于applet、BREW接口的载体是mod,所以要将applet、接口的最重要的信息记录在它所在的mod里,也就是mod的mif文件里。如果不在mif文件里记录,BREW就无法找到这个ClsID所在的Mod,Mod就无法启动,当然这个ClsID代表的applet或接口也就无法启动。

4、Mod的实体组成
Mod主要由两个文件组成:一个mif文件,一个mod文件。在模拟器环境下,mod文件的后缀是.dll,而在手机里,则要转成.mod后缀。
除了这两个主要部分外,根据具体的Mod,还会有资源文件(.bar)和其它mod需要的各种文件。
除此之外,为了能让Mod在真实手机里运行,还必须在qualcomm官方网站注册生成Mod签名文件(.sig),如果没有有效的签名文件,Mod在手机里是无法运行的。签名文件的文件名必须与mif文件名同,与mod文件在同一目录中。签名文件有两种:测试签名和正式签名,分别针对不同的目的。

5、Mod的加载和启动
启动一个applet一般使用如下语句:
ISHELL_StartApplet(..., clsid);
创建一个BREW接口的实例一般使用如下语句:
ISHELL_CreateInstance(..., clsid);
可以看到,都要传入ClsID,在第一节已经说了,BREW只启动到Mod为止,看完下文你便会明白。

5.1 加载Mod
BREW看到clsid后,会查询所有它能找到的.mif文件,目的是要知道这个clsid是属于哪个mod的,如果a.mif里有这个clsid,那么BREW就会调用Mod a的ModLoad函数加载这个Mod,对于动态应用,就是将动态mod的执行程序从文件系统搬进内存,并创建Mod的实例。对于静态应用,则只是创建Mod的实例。
所谓创建Mod的实例,其实就是创建IModule接口的实例。也就是说所有mod被加载后都会以一个IModule接口实例的形式存在。读者会问,不同的Mod对应的IModule实例有什么不同?为了不致于偏题太多,此问题将在idle的其它文章里讲述。

5.2 启动Mod
 加载Mod只是创建了一个Mod实例,而启动Mod则是要让Mod动起来。 BREW的工作只有一步:调用IModule接口的接口函数IModule_CreateInstance,此函数有一个参数用来接收Clsid.
到此BREW的任务完成,正如第一节所述,那么接下来Mod是如何决定启哪个应用或接口的呢?
对于动态Mod来说,IModule_CreateInstance会触发一个固定的函数AEEClsCreateInstance,并将clsid继续传给AEEClsCreateInstance,在BREW里只有对此函数的声明,所以每一个动态Mod都要实现此函数,并且函数名固定,否则这个Mod是无法启动的。如果开发者打算将多个Applet打包成一个动态Mod,则在AEEClsCreateInstance的实现里就要对入参clsid作判断,对于接收到不同的clsid,则启动不同的applet。如果打算一个动态Mod里只放一个applet,那么就可以省去对clsid的判断,而直接启动这个applet即可。
所以说,与其说是mod来决定启动哪个应用或接口,还不如说是开发者自已决定的。
看过002篇的读者一定知道,在002篇里对AEECLSCREATEINSTANCE作了讲述,并将其称为扩展接口的入口函数,在002篇的例子里,扩展接口IStringParse自成一个mod,所以AEEClsCreateInstance里没有对clsid做判断,而是直接调用了IStringParse的new函数创建IStringParse的实例。
下面这段代码说明了当一个Mod里有多个applet或(和)接口时是如何处理的。
int AEECLSCREATEINSTANCE(...., clsid)
{
 if(AEECLSID_INTERA == clsid) //如果clsid等于AEECLSID_INTERA,启动接口A
 {
  return newA(); //接口A的new函数
 }
 else if(AEECLSID_APPB == clsid) //如果clsid等于AEECLSID_APPB,则启动applet B
 {
  return IApplet_New(..., ); //所有applet的实例创建函数,由IApplet接口统一提供
 }
 else if(AEECLSID_APPC == clsid) //如果clsid等于AEECLSID_APPC,则启动appletC
 {
  return newC(); //也可以不直接调用IApplet_New, 而放在newC函数里调用。
 }
 else
 {
  return EFAILED;
 }
}

6、在simulator中运行动态Mod
将Mod的mif文件放入simulator的MIF directory下;在simulator的Applet Dir下新建一个目录,目录名与mif文件名同,将Mod的其它文件放入此目录下即可。运行simulator,在applet列表中就能看见Mod里的所有Applet。

本篇到此完。

原创粉丝点击