在前文中我们给大家介绍了如何将MIDlet应用移植到BlackBerry,本文我们将介绍《BlackBerry应用和MIDlet之间的交互》。
用RMS在MIDlet和BlackBerry之间共享数据
对于很多没有BlackBerry应用经验的开发者,或者对于很多现有的Java ME的系统,如果以最小的代价和BlackBerry应用交互,或者和BlackBerry应用集成,这是一个很好的方法。同时,这也是对老的Java ME应用和BlackBerry的新应用迁移和同步数据的一个好办法。既然BlackBerry开发对Java ME提供支持,所以RMS可以被用来作为这种解决的首选。
原来的MIDP规范定义了持久的,基于记录的存储功能叫记录管理存储(RMS)。一个MIDlet套件可以使用RMS创建一个或多个记录存储,每个由一个独一无二的名字标识。在javax.microedition.rms包中可以找到必要的类和接口。Record Store提供了打开,关闭,读取,写入和更新操作,也提供方法删除单个记录或者整个存储。这个包包含接口来列举,排序和筛选RMS内容。
在MIDP1.0时候,每个RMS存储只属于创建它的MIDlet套件。MIDP2.0规范给RMS包增加了一个非常有用的能力:它允许一个MIDlet套件和另一个MIDlet套件共享记录存储。
如何共享
共享一个RMS记录存储需要两个或者多个参与者:一个拥有者和一个或者多个消费者。拥有者负责创建和命名存储和建立授权模式-共享或者不共享-和它的访问模式-可写或者不可写。消费者通过名字获得记录存储的访问。消费者不能访问没有共享的存储,也不能修改不可写的存储。一个共享的RMS被一个三元组标识(提供者名字,MIDlet套件名字,记录存储名字):
◆提供者名字是JAD或者manifest文件里面的MIDlet-Vendor属性的值。
◆MIDlet套件名字是JAD文件里面MIDlet-name字段的值
◆记录存储名字是一个1到32位长的区分大小写的Unicode字符串,是当你创建记录存储时候用的名字。
要支持共享,MIDP2.0标准在javax.microedition.rms中添加了两个字段和三个方法第一个新方法打开一个已经存在的记录存储,或者创建一个新的记录存储并设置它的授权和可写特性。
- static Record Store
- Open Record Store(Stringrecord Store Name,booleancreate,intauthmode,booleanwritable);
参数如下:
record Store Name设置记录存储的名字sets th ename of there cord store.create,如果为true,创建并不存在的存储.
authmode指定授权模式specifies the authorization mode:Record Store.AUTHMODE_PRIVATE阻止共享or Record Store.AUTHMODE_ANY允许共享.如果存储已经存在这个参数会被忽略.
writeable,如果为true,指定其他MIDlet套件可以修改这个记录存储.如果存储已经存在这个参数会被忽略.
消费者打开一个共享的记录存储的方法如下:这里:
◆recordStoreName是要打开的共享记录存储的名字
◆vendorName是拥有者MIDlet套件的MIDlet-Vendor属性的值
◆suiteName是拥有者MIDlet套件的名字
仅当记录存储的拥有者设置了automode为AUTHMODE_ANY时这个方法才能成功打开记录存储。需要注意的是你不能直接检测存储的可写属性。要发现一个记录存储是否可写的唯一方法是试着向记录存储写入,如果不可写就捕获相应的异常。
记住在JAD或者manifestMIDlet-Version,并不在参数列表中。这意味着拥有者套件无法在影响消费者的前提下改变共享的存储的记录格式。
最后一个新方法如下:
- vo id
- s et Mo d e ( in t au th m o d e, b oo le an w rit ab le ) ;
这里:
authmode指定记录存储的新的授权模式specifiesthenewauthorizationmodeofthe,
AUTHMODE_PRIVATE或者AUTHMODE_ANY.
writable指定存储的信息可写模式specifiesthestore'snewwritablemode.
只有拥有者MIDlet套件才能改变authmode和writable属性.没有方法能够用来查询这些设置
总结:
在原有老的MIDlet应用中创建使用了RMS之后,在BlackBerry中直接打开就可以操作了,反过来也是。
使用全局事件来进行应用交互
BlackBerry平台提供了事件模型,用来在不同的应用之间通信,在使用事件模型的时候需要注意如下事项:
◆任何应用程序都可以发布或者监听全局事件
◆通过响应全局事件可以在一个应用程序中执行一些本来应该在另一个应用中出现的动作
◆通过发送全局事件也可以在应用程序之间传递数据
定义全局事件
对于全局事件的定义,BlackBerry有自己的定义规范:
◆定义一个ID变量
◆把ID变量定义为静态的,从而使得其他的类也可以引用到
◆通对包名做HASH产生ID,使ID变得独一无二
示例代码如下
- class Glo b al Ev entFi ring Ap p e xt end s UiApp li catio n {
- / / ID w il l be hash o f pac kage na m e
- pub li c stati c lo n g GLOB AL_ID = 0 xba4b 8 4 9 4 4 bb 74 29 e L ;
发布一个全局事件
通过把事件ID传递到postGlobalEvent()方法中,我们可以发布一个全局事件
BlackBerry提供了有四种不同的方法来发布发布一个事件示例代码如下
- / / p o st t h e gl o b al ev en fr o m y o u r app li cati o n aft er s o m et h in g
- / / m eaning fu l ha s happ e n ed
- App li ca tio n M an ag er.g et App li catio n M an ag e r()
- .p o stGl o b alEv ent(G L OBAL_ ID) ;
- / /o r a po st p assin g o the r in fo r m ati o n
- App li ca tio n M an ag er.g et App li catio n m an ag er()
- .p o stG o lb alEv ent(G L OBAL_ ID,data0 ,d ata1 ,o b j ect 0 ,o b j ect 1 );
对于事件接受者来说,需要考虑和实现的关键点如下
◆全局监听应用程序必须要是一个自动启动应用程序
◆监听程序需要有类能够实现一个GlobalEventListener接口
◆监听程序需要添加GlobalEventListener实例
示例代码如下:
- class Gl o b alEv entL is te n erA p p e xt end s UiApp li catio n i m p le m ents Glob alE ve n tL i ste n e r {
- …
- pub li c Glob alEv entL i ste n er App () {
- add Glob alE v en tL ist ener(t h is);
对于GlobalEventListener接口,来说应用需要注意的是,必须要实现具体事件影响的方法,示例代码如下:
GlobalEventListener接口只有一个必须要实现的方法不管事件怎么发布的,这个方法都是一样的
- // thi s m et h o d is ex ecu te d when a gl o b al e v ent has be en po st ed pub li c vo id ev entOc cur ed(l o n g gu id , int data 0 , int da t 1 ,
- Object o b je ct0 , Ob je ct o b je ct1 ) {
- / / che ck the I D o f t h e po st in g app
- if (gu id = = Gl o b alE v entFi ri ng App .GLOBAL_ ID ) {
- / / d o som et h in g m eaning fu l here
- / / v ari ab les that w ere passed in can b e u sed d epen d in g
- / /o n w h at po st o ccurr e d . O ther wise the v alu e will be nu ll
- }
- }
使用RUNTIMEStore来应用交互
相对于静态的RMS的繁琐配置和不灵活,BlackBerry提供的运行时存储(runtimestore)非常灵活和方便,它在平台即被提供了如下功能。
◆运行时存储提供一个中间区域让不用应用可以共享对象
◆通过数字签名的任何应用程序都可以访问运行时存储
对于运行时存储–存储数据的使用需要注意的是:
◆对象可以添加到运行时存储或者从运行时存储中替换掉
◆运行时存储必须以一个独一无二的ID创建
◆任何类型的对象都可以放到运行时存储中
这里是创建运行时存储和写入简单数据的代码示例
- class Crea te St o re D e m o e xt end s UiApp li catio n {
- / / cr eate t h e ID bas ed o n p ackage na m e
- pub li c sta tic l o n g STOR E_I D = 0 x 23 ad 2 3 4 8 9 a 2 4 3 L ;
- pub li c Crea te St o re D e m o ( ) {
- Strin g m sg = “ Sh ared te xt f o r ano ther app li ca tio n ” ; Run ti m eSt o re st o re = R un tim eSt o re.g e tRun ti m eSt o re() ; try {
- st o re.pu t(ST ORE_ I D , m sg );
- } ca tch (E xce p tio n ex ) {}
- }
- }
创建好了以后,这里就是读取运行时候存储的代码示例
- class Re ad Sto r eD em o ex te nd s UiApp li catio n {
- pub li c ReadS t o r eD em o () {
- Run ti m eSt o re st o re = R un tim eSt o re.g e tRun ti m eSt o re() ;
- try {
- / / cast t h e return ed o b ject to a st rin g
- S trin g m sg = ( S tring )st o re.g et (Crea te St o re D e m o . STORE_ I D ) ;
- } ca tch (E xce p tio n ex ) {
- / / h and le e xce p ti o n
- }
- }
- }