开发BREW扩展类.docx
- 文档编号:10859480
- 上传时间:2023-02-23
- 格式:DOCX
- 页数:21
- 大小:86.61KB
开发BREW扩展类.docx
《开发BREW扩展类.docx》由会员分享,可在线阅读,更多相关《开发BREW扩展类.docx(21页珍藏版)》请在冰豆网上搜索。
开发BREW扩展类
看到一篇文章,觉得比较有指导意义,译过来,希望给大家有些帮助,能力有限,有错误的地方还望大家指出来。
共同学习,共同进步。
原文地址:
1简介:
扩展类可以扩充BREW的功能,通常来说,扩展类都是以动态的形式存在并且以OTA方式提供下载,然而在某些情况下,OEM制造商会在他们的设备中添加了一些静态的扩展类,例如:
OEM制造商经常会给BREW标准接口类IAddrBook添加许多额外的功能,他们通常会创建自己的IAddrBook接口,并且把新增的额外功能提供给开发者。
2静态VS动态
静态扩展类通常是被包含在OEM制造商的SW版本中,不由第三方开发者提供。
从另外一个角度看来,动态扩展则是由OTA方式下载。
移动应用和它所需要的扩展类是同时被下载到手机上的(除非手机上已经存在了所需的扩展类),通过MIF文件提供的依存列表信息把所需要的扩展类下载到手机当中。
每一个动态扩展都会有一个相关联的引用计数,该引用计数负责监视手机上所有应用对于该扩展类的依赖关系,如果引用计数减少到0,则该扩展类将被从手机内存中移除。
静态扩展则不是,它没有引用计数,也永远不会被从手机上删除。
3特性
扩展类不包含权限设置,它的权限级别继承于父应用,例如:
如果某应用使用了一个具有文件操作功能的扩展类,那么该应用就是扩展类的父应用,除非父应用的MIF文件中设置了允许文件操作的权限,否则该扩展类的所有文件操作都会失败,这一点对于扩展来开发人员来说十分重要。
与权限级别相似的是,扩展类中所有对于文件的操作都是通过父应用的上下文来执行的,如此来看,对于父应用不可见的文件,扩展类也是无法操作的。
扩展类即可以是保护类型也可以是未保护类型。
对于保护类型来说,如果父应用的MIF文件中的依存关系列表中有显示罗列出该扩展类,那么父应用就可以创建并使用它,反之,则不行;对于非保护类型则可以被所有应用使用,不用考虑该应用是否明确声明了依存关系,这样的扩展类通常被加上一个MIME类型的标记,应用只需要通过外壳查找目标MIME类型的句柄,就可以使用它的功能了。
4MIF文件
扩展类和应用一样需要MIF文件,然而,他们却在根本上有所不同。
首先,一个扩展类的MIF文件不需要定义一个applet,只需要在MIF编辑器的"Externsions"标签栏中的"ExportedClasses"中设置其classID即可。
保护类型的属性也在该标签栏中设置。
如果一个应用的运行以来与一个扩展类,那么在该应用的MIF文件中必须把扩展类的classID设置为依赖,如果没有此类依赖关系,该扩展类将不会在下载应用的时候被一同下载,当该应用运行的时候就会失败。
如果扩展类是可选的,就可以不用添加依存关系,然而应用必须能够处理扩展类不存在的情况。
5声明扩展类的结构体
第一步,开发扩展类首先需要声明虚函数表。
typedefstructIDemoExtensionIDemoExtension;
AEEINTERFACE(IDemoExtension)
{
INHERIT_IQueryInterface(IDemoExtension);
int(*DisplayTime)(IDemoExtension*po);
int(*DisplayDate)(IDemoExtension*po);
};
第一行声明了一个IDemoExtension的结构体,该结构体是一个apple结构体,将会返回给正在初始化的应用,其中的宏AEEINTERFACE声明了一个扩展类的虚函数表,从上面的声明看出,虚函数表中有5个函数。
BREW的每一个接口类都定义了一个类似于上面定义中的宏INHERIT_XXX,用它来把已继承的函数添加到已存在的函数表中,至少,BREW强烈推荐如上例所示,从IQueryInterface派生而来。
宏INHERIT_IQueryInterface添加三个函数到函数表中:
AddRef,Release,QueryInterface。
我们的例子中添加了DisplayTime和DisplayData两个函数。
下一步我们定义宏来索引我们函数表中的函数
#defineIDEMOEXTENSION_AddRef(p)
AEEGETPVTBL((p),IExtensionCls)->AddRef((p))
#defineIDEMOEXTENSION_Release(p)
AEEGETPVTBL((p),IExtensionCls)->Release((p))
#defineIDEMOEXTENSION_QueryInterface(p)
AEEGETPVTBL((p),IExtensionCls)->QueryInterface((p),(clsid),(pp))
#defineIDEMOEXTENSION_DisplayTime(p)
AEEGETPVTBL((p),IDemoExtension)->DisplayTime((p))
#defineIDEMOEXTENSION_DisplayDate(p)
AEEGETPVTBL((p),IDemoExtension)->DisplayDate((p))
上面的宏可以供父应用来调用扩展类的函数,宏AEEGETPVTBL能准确地指向函数表,并能方便的调用到函数表中的函数,需要注意的是AEEGETPVTBL是同AEEINTERFACE配合起来使用的,我们一旦声明好虚函数表,那么就应该定义扩展类结构体了。
以上代码的第一行把虚函数表插入了扩展类的结构体定义之中,虚函数表必须总是被定义成为结构体的第一个成员,m_nRefs变量也必须在结构体定义中声明,一个扩展类在应用中将会数次被引用,这个变量用来保存在应用中被引用的总次数,AddRef和Release函数是用来对该变量进行增减操作的,一旦m_nRefs变为0,该扩展类就会释放所有占用的资源。
结构体中接下来的三个成员是扩展类的可选成员,可以在扩展类中添加任何所需要的成员变量。
6定义函数
定义的第一个函数必须是AEEClsCreateInstance,REW总是调用该函数来创建该class的接口,下面的代码表明了普遍实现的方法。
intAEEClsCreateInstance(AEECLSIDClsId,IShell*pIShell,
IModule*po,void**ppObj)
{
*ppObj=NULL;
if(ClsId==AEECLSID_MYEXTENSION){
returnMyExtension_New(sizeof(IDemoExtension),pIShell,po,
(IModule**)ppObj);
}
returnEFAILED;
}
我们的函数首先会检查由BREW传入的参数classID,如果检查通过了,函数就尝试创建和初始化需要的资源。
intMyExtension_New(int16nSize,IShell*pIShell,IModule*pIModule,
IModule**ppMod){
IDemoExtension* pMe=NULL;
VTBL(IDemoExtension)* modFuncs;
if(!
ppMod||!
pIShell||!
pIModule)
returnEFAILED;
*ppMod=NULL;
//AllocatememoryfortheExtensionClsobject
if(nSize nSize+=sizeof(IDemoExtension); //Allocatethemodule'sstructandinitializeit.Notethatthe //modulesandappsmustnothaveanystaticdata. //Hence,weneedtoallocatethevtblaswell. if((pMe=(IDemoExtension*)MALLOC(nSize+ sizeof(VTBL(IDemoExtension))))==NULL) returnENOMEMORY; modFuncs=(VTBL(IDemoExtension)*)((byte*)pMe+nSize); //InitializeindividualentriesintheVTBL modFuncs->AddRef =MyExtension_AddRef; modFuncs->Release =MyExtension_Release; modFuncs->QueryInterface =MyExtension_QueryInterace; modFuncs->DisplayTime =MyExtension_DisplayTime; modFuncs->DisplayDate =MyExtension_DisplayDate; //initializethevtable INIT_VTBL(pMe,IModule,*modFuncs); //initializethedatamembers pMe->m_nRefs =1; pMe->m_pIShell =pIShell; pMe->m_pIModule =pIModule; //AddReferencesandgetIDisplay ISHELL_AddRef(pIShell); IMODULE_AddRef(pIModule); //CreateaninstanceoftheIDisplay if(ISHELL_CreateInstance(pIShell,AEECLSID_DISPLAY, (void**)&pMe->m_pIDisplay)! =SUCCESS) returnEFAILED; //Setthepointerintheparameter *ppMod=(IModule*)pMe; returnAEE_SUCCESS; } AddRef,Release和QueryInterface是从IQI接口继承过来的,AddRef负责增加引用计数的数值。 staticuint32MyExtension_AddRef(IDemoExtension*pMe){ //Incrementreferencecount return++(pMe->m_nRefs); } Release函数负责减少引用计数的数值,当引用计数的值变为0的时候,该实例就会从内存中被释放掉。 staticuint32MyExtension_Release(IDemoExtension*pMe){ //Decrementreferencecount if(--pMe->m_nRefs! =0) returnpMe->m_nRefs; //Refcountiszero. Releasememoryassociatedwiththisobject. if(pMe->m_pIDisplay) IDISPLAY_Release(pMe->m_pIDisplay); //Releaseinterfaces ISHELL_Release(pMe->m_pIShell); IMODULE_Release(pMe->m_pIModule); //Freetheobjectitself FREE_VTBL(pMe,IModule); FREE(pMe); return0; } 我们最后一个需要定义的函数就是QueryInterface,这个函数返回一个与扩展类相关联的接口,IWeb接口就是一个例子,当一个应用使用该接口完成一个网页请求的时候,底层的一个TCP套接字被创建,为了能够直接控制这个套接字,应用可以通过调用IWeb_QueryInterface函数,传递参数AEECLSID_SOCKET(AEECLSID_SOCKPORT在BREW3.x中),来获得这个接口,该函数将返回一个指针,下面是QueryInterface的一个具体实现。 staticintMyExtension_QueryInterface(IDemoExtension*me, AEECLSIDclass,void**ppo){ switch(class){ caseAEECLSID_QUERYINTERFACE: caseAEECLSID_MYEXTENSION: caseAEECLSID_BASE: *ppo=me; MyExtension_AddRef(me); returnSUCCESS; caseAEECLSID_DISPLAY: *ppo=me->m_pIDisplay; returnSUCCESS; default: *ppo=NULL; returnECLASSNOTSUPPORT; } } 7静态扩展类 上面介绍的这个例子也可以用来创建静态扩展类,然而静态扩展类可以作为全局变量,有了这个特性,下面的代码可以为静态扩展类构造虚函数表。 staticconstAEEVTBL(IDemoExtension)gvtIDemoExtension={ MyExtension_AddRef, MyExtension_Release, MyExtension_QueryInterface, MyExtension_DisplayTime, MyExtension_DisplayDate, }; 以上的代码被放置在函数之外,通常是在一个头文件中,初始化扩展类可以简单的用一行代码搞定。 pMe->pvt=&gvtIDemoExtension; 上面的代码初始化了整个虚函数表,不必对于虚函数表中每个函数都初始化一次,然而上面的代码仅对静态扩展类是有效的,一个动态扩展类的地址是在运行时确定的(于之不同的是,静态扩展类的地址是在编译时确定的),因此,虚函数表必须在运行时声明。 8关于宏 强烈推荐在以上例子中所使用到的宏,然而在BREW中还有许多其他的可以用来创建扩展类的宏。 其中很多宏被包含近来是为了向后的兼容性,一些宏例如: QINTERFACE,GET_PVTBL和DECLARE_IBASE都是十分令人气馁的,他们应该分别被AEEINTERFACE,AEEGETPVTBL和INHERIT_IQueryInterface替代。 9使用扩展类 扩展类可以像标准的BREWAPIs一样被创建和释放,每个函数都可以通过头文件的宏定义来调用,同BREWAPIs一样,在编译调用扩展类函数的应用的时候需要包含其头文件,下面的例子叙述了如何在应用中调用扩展类的函数。 if(ISHELL_CreateInstance(pMe->a.m_pIShell,AEECLSID_MYEXTENSION, (void**)(&(pMe->pIDemoExtension)))! =SUCCESS){ returnFALSE; } IDEMOEXTENSION_DisplayTime(pMe->pIDemoExtension); if(pMe->pIDemoExtension){ IDEMOEXTENSION_Release(pMe->pIDemoExtension); pMe->pIDemoExtension=NULL; } 10通过MIME类型使用扩展类 扩展类可以把其自身注册为一个MIME类型的句柄,它的注册最好通过MIF编辑器来完成。 上面提及的例子展示了一个扩展类注册为MYTIME句柄,MIME类型的注册允许在运行时解决classID的问题,应用可以通过ISHELL_GetHandler函数找到一个MIME类型的classID,整个函数会遍历所有的MIF文件,寻找以MIME类型方式注册的classID。 下面这个例子阐述了一段能创建和显示多种不同格式文件的代码,在此例中,有一个抽象类IReader,一个扩展类可以扩充它的接口来显示多种格式的文件。 //AnApplicationwillcallthisfunctionwhenitintendsto //openafile voidDisplayFile(MyApp*pMe,char*mime,char*file){ AEECLSIDmyClass; //ThiscallwillcreateahandlerforMYPDF,MYDOC,or //MYXMLdependingonmime myClass=ISHELL_GetHandler(pMe->pIShell,AEECLSID_APP,mime); //CreatenecessaryInterface ISHELL_CreateInstance(pMe->pIShell,myClass,&pMe->pIReader); //IshellCreateinstance //EachextensionimplementsDisplayFile,Thevirtual //tablewillpointtothecorrectcorrespondingfunction //call. Weareignoringerrorchecking IREADER_DisplayFile(pMe->pIReader,file); } DisplayFile是一个被所有扩展类实现的扩充IReader的接口,虚函数表在创建扩展类的时候被初始化,这样就使IREADER_DisplayFile可以索引正确的函数来显示文件。 11更多信息 BREW2.x察看AEE.h BREW3.x察看AEEInterface.h DevelopingBREWExtensions Introduction ExtensionsbroadenexistingBREWfunctionality.Typically,extensionsaredynamicandmaybedownloadedovertheair(OTA).However,insomecases,OEMsaddstaticallybuiltextensionstotheirdevices.Forexample,OEMsoftenaddadditionalfunctionalitytothestandardBREWIAddrBook.Inthiscase,OEMswilloftencreatetheirownIAddrBookextensionandexposeadditionalfunctionalitytodevelopers.Thefollowingdocumentationexplainstheprocessofdevelopingbothstaticanddynamicextensions. StaticVs.Dynamic StaticextensionsarebuiltintotheOEM’sSWbuildandarenottypicallydevelopedbythirdpartydevelopers.Dynamicextensions,ontheotherhand,aredownloadableOTA.Applicationsandtheirrequiredextensionsaredownloadedduringthesametransaction(unlesstheextensionalreadyexistsonthehandset).Dependencylistswithinanapplication’sMIFfileinformthedevicetodownloadanyadditionalrequiredextensions.Eachdynamicextensionhasanassociatedreferencecount.Thisreferencecountkeepstrackofallapplicationsonadevicethathaveadependencyonthatextension.Ifthisreferencecountisdecrementedto0,thentheextensionisremovedfromthedevice.Staticextensionsdonothavereferencecountsandareneverdeletedfromthedevice. Properties Extensionsdonotcontainprivilegesettings.Privilegeslevelsareinheritedfrom
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 开发 BREW 扩展
![提示](https://static.bdocx.com/images/bang_tan.gif)