如何将MIDlet应用移植到BlackBerry(四)
2010-09-13 23:47
204 查看
作者:
邓明轩、王恒进、王志刚
使
用
P
ersist
ent
S
t
or
e
进行存储
在
Bla
ck
Be
rr
y
平
台上
还可
以通
过
P
er
s
ist
en
tS
t
o
r
e
存储
数据,
这种
方法
可以
将对
象直接
保
存在设
备内
存中
,
需
要使
用的时
候可
以通
过
AP
I
从
设备内
存中
直接
读取
出来
,
读取
出来
看获
得的是一
个
o
bjec
t
对
象,
需要开
发人
员对
该对
象进
行强制
转换
。
相比
RunT
im
eSt
o
r
e
,
P
er
s
ist
en
tS
t
o
r
e
的好处
是可
以持
久保存
数据
,即
使设
备掉
电数据
也
不会丢
失。
不过
,使用
P
e
r
s
ist
en
t
S
t
o
r
e
要求被
保存的
数据必
须实现
P
er
s
ist
ab
le
接口。
如下
面
代码所
示,
如果
希望
将
My
Da
t
a
实例
保存
在
P
er
s
ist
en
tS
t
o
r
e
中,
M
yDa
t
a
类
需要实
现
P
er
s
ist
ab
le
接口:
public
class
MyData
implements
Persistable
{
//
其中为
MyData
的
方法和
属性定义
。
}
在
P
er
s
ist
en
tS
t
o
r
e
中保
存的
对象以
一个
长整型
的
ID
作
为标记
,
保存
或者
是获
取该
对象都
以这个
长整
型的
I
D
作
为参
数。为
了保
证所
保存
的对
象和其
它应
用保
存的
对象
不冲突
,可
以
通过
ha
s
h
算
法通
过包
名生
成一个
长整
型
ID
。
Bla
ck
Ber
ry
E
cl
ips
e
P
lu
g-i
n
环境
也提
供了一
个方
法将字
符串
转换
成长
整型
,选中
某一
行字
符串
,点
击右键
,选
择“
Co
n
v
er
t
St
r
in
g
t
o
lo
ng
”,
可以将
选中
的字
符串
转换
成长整
数。
无论用
什么
方式
生成
长整
数,对
象
ID
的定
义语
句都
类似于
以下
代码
:
public
static
long
PersistentID
=
0x815402392d453a9d
L;
定义
了
P
er
s
ist
en
t
ID
后,可
以通
过
P
er
s
ist
en
tS
t
o
r
e
的静
态方
法
g
et
P
er
s
ist
en
t
Ob
ject
获得所
保存的
持久
化对
象,
g
et
P
e
r
s
ist
en
t
Ob
ject
方法只有一
个参数
,为
保存
对象
的
ID
,本例
使用
上
面定义
的
P
er
s
ist
en
t
ID
。
获得持
外化
对象
以后
,可
以通过
该实例
的
g
et
Co
n
t
en
t
s
方法获
得真
正保
存在设
备内存
的
对象,
可以通
过
s
et
Co
n
t
en
t
s
将内存中
的对
象保
存到
持久化
对象
中。
在获
得对
象的过
程中
记
得要将
返回
的
Ob
j
ect
实例
强制转
换为
你使
用的类
。
在保存
对象
时记
得要调
用
P
ers
ist
en
tSot
r
e
的
c
omm
it
方法
完成
保存动
作。
P
ers
ist
en
tS
t
o
r
e
使用
的代码
片段如
下:
PersistentObject
persistentStore
;
persistentStore
=
PersistentStore.
getPersistentObject
(
PersistentID
);
synchronized
(
persistentStore
)
{
if
(
persistentStore
.getContents()
==
null
)
{
myData
=
new
MyData();
persistentStore
.setContents(
myData
);
persistentStore
.commit();
}
else
{
myData
=
(
MyData)
persistentStore
.getContents();
}
}
}
使
用
SQLit
e
进
行
存
储
在
Bla
ck
Be
rry
5
.
0
以
上的
平台上
提供了
对
S
ql
it
e
的
支持,
使开
发人
员可以
在
Bla
ck
Be
rry
手机上
使用
关系
型数
据库
。对于
将
MI
Dl
et
移植
到
Bl
ac
kBe
rry
上的
开发
人员
而
言,这
无疑
是
一个好
消息
,使
用关
系型
数据库
保存
数据
可以
让程
序更加
简单
有效
。
当然,
决定
是否
将数
据存
储方式
由之
前的
RMS
转变
为关系
型数
据库
,具
体要
看应用
的
规模和
数据
类型
。
一
般而
言,
如
果应
用规
模不
大,
数据类
型更
接近
树状
的文
档结构
,
则
不建
议使用
关系
型数
据库
。
反
之,
如果
应用
规模较大
,
而且需
要存
储的
数据
是大
批量的
规整
的数
据,则
使用
关系
型数
据库
比较有
利。
从具体
实现
上讲
,在
Bla
ck
Berr
y
平
台上
有
Da
t
ab
a
s
eF
a
ct
o
ry
可以用
于创
建或
者是
连接数
据库,
所创
建的
数据
库以一
个文件
的形
式保
存在
设备
中,
可
以是
设备
内存,
也可
以是媒
体卡
。
创
建
或
者
是
连
接
数
据
库
以
后
获
取
了
Da
t
ab
a
s
e
实
例
,
可
以
通
过
Da
t
ab
a
s
e
实例
的
cre
a
t
eSt
a
t
emen
t
方
法创建
一句
S
QL
语句
,通
过
S
t
a
t
emen
t
实例
的
pr
ep
ar
e
方法
准备执
行,
然
后通过该实例
的
e
x
ecut
e
方法执行。如
果是查询语句,可以
在
p
r
epa
r
e
方法执行后,通
过
g
et
Cu
r
so
r
获
得查
询结
果的
光标,
再通
过光
标操
作获
得所查
询的
内容
。
下面是
创建
或者
是连
接数
据库的
语句
:
String
dbLocation
=
"/SDCard/databases/SQLite
Demo
/"
; URI
uri
=
URI.create
(dbLocation
+
"mydb
"
);
Database
db
=
DatabaseFactory.
openOrCreate
(uri,
new
DatabaseSecurityOptions(
false
))
;
下面是
执行
查询
语句
的代
码片段
:
Statement
statement
=
_db
.createStatement(
"SELECT
*
FROM
Category"
);
statement.prepare();
Cursor
cursor
=
statement.getCursor();
下面是
查询
后遍
历结
果的
代码片
段:
Row
row;
int
id; String
nam
e;
while
(c
ur
s
or
.n
ex
t(
))
{
ro
w
=
c
ur
so
r.
ge
tR
ow
()
;
id
=
r
o
w.
ge
tI
nt
eg
er(0);
na
me
=
ro
w.
ge
tS
tr
in
g(
1)
;
}
使用完
之后
记得要
将
S
t
a
t
emen
t
实例
和
Cu
r
so
r
实例关
闭,如
:
statement.
close();
cursor.clo
se();
对于
S
QLi
t
e
的使用
,
关键
点是
S
QLi
t
e
是一
个轻
量级
的
S
QL
数
据库
,
不能
支持
所有
的
S
QL
功能。
一
方面
是在
数据格
式上只
支持
简单
的类
似
In
t
eg
er
,
T
e
xt
这
样的
类型,
另
一方面
是所
支
持的
S
QL
语句
也有
限,不
支持复
杂的
查询
操作
。
有关
S
QLi
t
e
的更
多信
息可
以在下
面的
网站
中找
到:
h
t
t
p://www
.s
ql
it
e.o
r
g
/
使用全局事件
来进行应用交
互
对于应
用通讯
,
只能
共享
数据是
不足
够的
,
在
共享
数据之
后需
要通
知相
应的
应用
,
让
目
标应用
可以
对数
据变
化进
行响应
。
Bla
ck
Be
rry
平台
提供
了事
件模型
,用
来在
不同
的应
用之间
通信
。
Bla
c
kBe
rry
上的任
何应
用程序
都可
以发
布或
者监
听全局
事件
,发
布全
局事
件的时
候需
要指
定一
个事
件
ID
号
,一
个
应用所
发布
的事
件会
被所
有监听
全局
事件
的应
用获
取,不
同的
应用
需要
通过
I
D
号判
断是
否
对该事
件进
行处
理。
另外
,
在
发送
全局
事件的
过程
中可以
同时
发送
一些
简单
的数据
,
使用
起
来会更
简单
一些
。
但
是对
于大量
的数
据,
一般
采用
的方式
是先
将数
据保
存到
特定的
共享
空间
中,然
后通
过事
件通
知目
标应用
。
首先需
要定
义一
个全
局事
件,对
于全
局事
件的
定义
,
Bla
ck
Ber
ry
有自
己的
定义
规范:
l
定义一
个
ID
变量
l
把
ID
变
量定
义为
静态
的,
从而使
得其
他的
类也
可以
引用到
l
通对包名
做
HA
S
H
产
生
ID
,使
ID
变得
独一
无二
示例代
码如
下
public
static
long
GLOBAL_ID
=
0xba4b84944bb7429eL;
定义了
全局
事件
后可
以将
该事件
发布
,
通
过把
事件
ID
传递
到
po
s
t
G
lo
ba
lE
v
en
t
(
)
方法中
,
我们可
以发
布一
个全
局事
件
Bla
ck
Be
rr
y
提
供了
有四
种不
同的方
法来
发布
一个
事件
,
简单的
方法
是只
传入事
件
I
D
不带
数据,
相对
复杂
的方
法在
发布事
件时
可以
传入
两个
整数作
为随
事件
发布
的内
容,
更
复杂
的可
以在发
布事
件时
传入
对象
作为发
布的
内容
。
开发
人员
可以根
据自
己程
序的
复杂
程序决
定使
用
什么方
法发
布一
个事
件。
最简单
的发
布事
件的
示例
代码如
下:
ApplicationManager.getApplicationManager()
.postGlobalEvent(GLOBAL_ID);
对于事
件接
受者
来说
,需
要考虑
和实
现的
关键
点如
下
·
全局监
听应
用程
序必
须要
是一个
自动
启动
应用
程序
·
监听程
序需
要有
类实
现一
个
G
lo
ba
l
E
v
en
t
List
ene
r
接口
·
监听程
序需
要添
加
G
lo
ba
lE
v
en
t
List
ener
实例
实现
Globa
lEven
t
L
ist
e
n
e
r
和添加
ClobalEve
nt
L
i
stene
r
的示例代码如下
:
class
GlobalEventListenerApp
extends
UiApplication
i
mp
le
me
nt
s
GlobalEventListener
{
public
GlobalEventListenerApp()
{
addGlobalEventListener
(
this
);
}
}
对于实
现
G
lo
ba
lE
v
en
t
List
ener
接口
的类
,
必
然实
现
ev
e
n
t
O
cc
ure
d
方法
以响
应全局
事件的
发生。
需要
注意
的一
点是
不管事
件由
谁发
布,
也不
管事件
是系
统事
件还
是程
序发布
的事件
,
只要有
事件
发生
,一
个注
册过
的
G
lo
ba
lEn
v
en
t
List
ene
r
的
ev
en
t
O
cc
ur
e
d
都会被
调用,
这意
味
着开发
人员
需要
自己
通过
事件
ID
进行
判断
,
如
果事
件
ID
属
于需
要处
理的
范围
才对事
件进
行
响应。
示例
代码
如下
:
public
void
eventOccured(
long
guid,
int
data0,
int
dat1,
Object
object0,
Object
object1
)
{
//
注意这里需要检
查事
件
ID
是不是
需要响
应的事件
。
if
(guid
==
Gl
ob
al
E
v
e
n
t
F
i
r
i
n
g
A
p
p
.GLOBAL_ID)
{
//
在这里完成事件响
应
}
}
接收推送数据
数据推送
是
Bla
ck
Be
rry
平
台的一
大优
势,
当服
务器
端有数
据更
新时
,
应
用服
务器可
以将
数据推
送到
手机上
,
不
需要
手机上
的应
用通
过轮
询的
方式检
查服
务器
上是
否有
需要更
新的
数
据。
有
关数
据推
送的
基本
架构与
服务
器的
推送
代码
,
请参
考
Bla
c
kB
er
r
y
推送
的相关
文档
,
文
小节只
描述
如何
在
MI
Dl
et
应用中
加上
手机
上侦
听推
送数据
的方
法。
应用自启动
如果希
望在
手机
端侦
听从
服务器
上推
送的
数据
,
一
般而言
需要
自动
启动
该侦
听应用
,
否
则有可
能该
侦听
应用
没有
启动,
导致
推送
数据
没有
被客户
端程
序接
收。
在
Bla
ck
B
er
ry
平台上要自动启动
一个应用程序比较简单,
可以直接通过设置完成,
在
Bla
ck
Be
rr
y
项
目中
双击
打开
“
Bla
ck
B
er
ry_
App
_De
s
cri
pt
o
r
.xm
l
”
,在
左边
“
G
en
er
al
In
f
o
rm
a
t
io
n
”
栏下方
选中
“
Aut
o
-run
o
n s
t
art
up
”就
可以
让该
项目中
的应用
在手
机启
动过
程中
自动启
动。
需要注
意的
是选
项“
Aut
o
-r
un
o
n
s
t
art
up
”只
有在
应用
类型为
“
Bla
c
kBe
rry
App
li
c
a
t
io
n
”
时可用
,也
就是
说如
果你
选择应
用类
型为
“
MI
Dl
et
”的话
就不
能使
用“
Aut
o
-r
un o
n st
art
up
”
选项。
所以需
要创
建一
个
Bla
c
kBe
rry
应用
进行
侦听
,而
不是
使用标准
的
MI
Dl
et
。
有关
Bla
ck
B
er
r
y
应
用项目
的创建
在这
里不
做详
细描
述,
需
要了
解具
体的
步骤
请参考
相关
文档。
创建
了
Bla
c
kBe
rry
项目后
首先
要考
虑应
用的
启动代
码,
Bla
ck
B
er
ry
应用
与普通
的
ja
v
a
应用一样
以
m
ai
n
方
法作为
入口。
为了更
好地
对应
用实
例进
行控制
,
这里
采用
单例模
式,
为类
P
us
he
dD
a
t
aLi
s
t
ener
创建
一
个静态
的单
例获
取方
法,
在
m
ai
n
函
数中
进行
调用
。
public
static
void
main(String[]
args)
{ PushedDataListener.
waitForSingleton
().start();
}
用
于
获
取单
例
的
静
态方法
实
现
如
下
,
一
如
普
通的单
例
获
取
方法
,
该方
法
的返
回
值
为
P
us
he
dD
a
t
aLi
s
t
ener
本
身
。在
该
方
法
中
,
使
用
了
R
un
t
im
eSt
o
r
e
将
实
例
保存
起来
,
如
果
在
Run
t
im
eS
t
o
r
e
中
已经
有实
例的话
则从
Run
t
im
eSt
o
r
e
中获取
,没
有则
创建
一个
新的实
例并
返
回。
public
static
PushedDataListener
waitForSingleton()
{
//
make
sure
this
is
a
singleton
instance
RuntimeStore
store
=
RuntimeStore.
getRuntimeStore
(); Object
o
=
store.get(
RTSID_MY_APP
);
if
(o
==
null
)
{
store.put(
RTSID_MY_APP
,
new
PushedDataListener());
return
(PushedDataListener)
store.get(
RTSID_MY_APP
);
}
else
{
return
(PushedDataListener)
o;
}
}
推送侦听
从上一
节的
启动
代码
可以
看到,
在应
用实
例得
到后调
用了
s
t
art
方法。
P
us
h
e
dD
a
t
aLi
s
t
ener
类
本
身
不
是
一
个
线
程
,
所
以
这
个
s
t
art
方
法
需
要
自
己
实
现
,
在
这
个
方
法
中
创
建
了
一
个
List
ener
Th
re
a
d
的
实例
,并
启动该
线程
。
List
ener
Th
re
a
d
实
例的
实现
主要是
创建
侦听
连接
,并
通过一
个不
结束
的循
环不
断从该
连
接中获
取服
务器
上推
送下
来的数
据。
首先需
要定
义
St
r
e
am
Co
nn
ect
io
nNot
ifi
e
r
实
例,
S
t
re
a
m
Co
nn
ect
io
nNot
ifi
e
r
用于
创建连
接。
其次需
要定
义
St
r
e
am
Co
nn
ect
io
n
和
In
putSt
re
am
,从
连接中
获取
到输
入流
,用
于侦听
数据
侦
听。
StreamConnectionNotifier
notify
=
null
; StreamConnection
stream
=
null
; InputStream
input
=
null
;
定义
St
r
e
am
Co
nn
ect
io
nN
ot
ifi
er
实例
后通
过
Co
nn
ect
o
r
的
o
pen
方法
打开
连接。
Co
nn
ect
o
r
是一个
标准
的类
,
用于连
接不同
连接
,
如
h
t
t
p
,
so
ck
et
等
。
连
接不
同网
络的时
候都是
使用
了
o
pen
方法
,在
参数
中传入
U
RL
打开
指定
的地
址。网
络的不
同类
型通
过
U
RL
参
数的不
同进
行
区分,
如
h
t
t
p
的
U
RL
以
“
h
t
t
p://
”
开
头,
而
so
ck
et
的
U
RL
是以
“
so
ck
et
:
//
”
开
头。
推
送数
据
不属于
其它
标准
的协议
,
所以它
的
U
R
L
格
式比
较特
殊,
格式
为:
“
h
t
t
p://
:
<po
rt
>
”
。
虽然
推送
的
U
RL
以
“
h
t
t
p://
”
开头
,
但是
它不
是一
个
h
t
t
p
请
求,
其
中的
“
<po
rt
>
”
为端
口号,
需要
和
服务器
推送
端约
定使
用同
一个端
口号
。
下面
是打开
边接的
代码
片段
,
其中
“
LIS
TEN
_U
R
L
”为
定义的
字符
串变
量,
值为
“
h
t
t
p://
:
9
1
1
”
,
其中
9
1
1
为约定
的端
口。
notify
=
(StreamConnectionNotifier)
Connecto
r.open
(
LISTEN_URL
);
获
得
连
接
后
需
要
将
连
接
强
制
转
换
成
St
re
am
Co
nn
ect
io
nNot
if
ier
。
获
得
St
re
am
Co
nn
ect
io
nN
ot
ifi
er
后就通
过一
个循
环不
断侦
听获取
推送
数据
。
循环的
第一
句为
not
ify
.a
cc
ept
And
Op
en
,
注意
这一句
语句执
行后
该线
程会
开始
等待,
不
再执行
,直
到有
推送
数据
到达。
推
送
数
据
到
达
后
ac
c
ept
And
Op
en
方
法
返
回
一
个
St
re
am
Co
nn
ect
io
n
实
例
,
通
过
St
re
am
Co
nn
ect
io
n
实例的
o
penI
np
ut
St
re
am
方法
可以
获得输
入流
,然
后通
过输
入流获
得推
送
数据。
注意操
作完
成后
需要
将输
入流
和
St
re
am
Co
nn
ect
io
n
关闭,
关闭
后重
新开
始侦
听,
等
待下
一个推
送数
据。
侦听的
代码
片段
如下
:
for
(;;)
{
stream
=
notify.acceptAndOpen();
input
=
stream.openInputStream();
//
在这里通
过对
input
的操
作获得推
送数据
input.close(); stream.close(); stream
=
null
;
}
另外需
要注
意的
是异
常处
理,
因为
连接
的建
立和
输入
流的处
理可
能会
因为
一些
原因抛
出
异常
。
一种方法是在循环内处
理
异常,处理完了继续循
环
,
但是这无
法
对
C
o
nn
ect
o
r
.o
pen
方法进
行处
理。
所以
需要
在循环
外对
异常
进行
处理
,
将
Co
nn
ect
o
r
.o
pen
包含
进来,
本文
的例
子就是
使用
这种
方法
。
但
是,
实际
而言
这种处
理方
式也有
问题
,
当输入
流处
理有问
题的时
候
会跳出
循环
,不
再侦
听推
送数据
。
最终建
议的
方法
是建
立两
重循环
,
在
两重
循环
都加
上异常
捕获
。
外
层循
环中
的异常
处理
负责处
理
Co
nn
ect
o
r
.o
pen
的异常
,出
现异
常的
话处
理后重
新通
过
Co
nn
ect
o
r
.o
pen
打
开连
接。
内层循
环对
输入
流异
常进
行处理
,
处
理后
继续
侦听
数据,
而不
需要
重新
通过
Co
nn
ect
o
r
.o
pen
打开连接
。
具
体代
码请
参考
开发环
境附
带的
样例
。
本文
为简化
代码
没有
采用
双重
循环的方式
。
侦听程序与主
程序的交
互
获取侦
听数
据后
需要
做的
工作是
通知
主程
序有
新数
据到达
,由
主程
序对
数据
进行处理
。
因为侦
听程
序为
后台
程序
,
不负
责界
面更
新等
操作
,
界面
更新
的操
作由
MI
Dl
e
t
主程序
完成
。
可以看
到关
键是
作为
侦听
程序
的
Bla
ck
Be
rr
y
应
用与
作为主
程序
的
MI
Dl
et
如何
交互,
这可
以
使用上
一章
节介
绍的
方法
,通
过
G
lo
ba
lE
v
en
t
通
知主
程序,
然后
将数
据写
入共
享数据
中。
主
程序在
接收
到事
件通
知后
共享数
据中
获得
推送
数据
再进行
数据
处理
和界
面更
新处理
。
具体
方
法不再
详细
描述
。
推送侦听的完
整代
码
下面是
推送
数据
侦听
的完
整代码
,不
包括
应用
交互
部分:
package
cn.searb;
import
java.io.IOException;
import
java.io.InputStream;
import
javax.microedition.io.Connector;
import
javax.microedition.io
.StreamConnection;
import
javax.microedition.io.StreamConnectionNotifier;
import
net.rim.device.api.system.RuntimeStore;
import
net.rim.device.api.ui.UiApplication;
public
class
PushedDataListener
extends
UiApplication
{
public
static
final
long
RTSID_MY_APP
=
0x68b31bd292413108L;
private
static
final
String
LISTEN_URL
=
"
ht
tp
:/
/:
91
1"
;
//
th
e
li
st
en port
private
ListenerThread
myThread
;
public
static
void
main(String[]
args)
{ PushedDataListener.
waitForSingleton
().start();
}
public
PushedDataLi
stener()
{
myThread
=
new
ListenerThread();
}
public
static
PushedDataListener
waitForSingleton()
{
//
make
sure
this
is
a
singleton
instance
RuntimeStore
store
=
RuntimeStore.
getRuntimeStore
(); Object
o
=
store.get(
RTSID_MY_APP
);
if
(o
==
nu
ll
)
{
store.put(
RTSID_MY_APP
,
new
PushedDataListener());
return
(PushedDataListener)
store.get(
RTSID_MY_APP
);
}
else
{
return
(PushedDataListener)
o;
}
}
public
void
start()
{
invokeLater(
new
Runnable()
{
public
void
run()
{
myThre
ad
.start();
}
});
this
.enterEventDispatcher();
}
class
ListenerThread
extends
Thread
{
public
void
run()
{
System.
out
.println(
"DemoOA
BackGroundThread
--
running"
); StreamConnectionNotifier
notify
=
null
;
StreamConnection
stream
=
null
; InputStream
input
=
null
;
try
{
sleep
(1000);
}
catch
(Exception
e)
{
}
try
{
notify
=
(StreamConnectionNotifier) Connector.open
(
LISTEN_URL
);
for
(;;)
{
stream
=
notify.acceptAndOpen();
input
=
stream.openInput
Stream();
//
stream.close();
stream
=
null
;
}
}
catch
(IOException
e)
{ System.
err
.println(e.toString());
}
finally
{
try
{
if
(stream
!=
null
)
{
stream.close();
}
}
catch
(Exception
ex)
{
}
try
{
if
(notify
!=
null
)
{
notify.close();
}
}
catch
(Exception
ex)
{
}
}
}
}
}
小结
通过本
文的
介绍
读者
可以
发现,
将
MI
Dl
et
程序
移植
到
Bla
ck
Be
rr
y
上
并不
困难
,同时
开
发人员
也可
以根
据项
目的
时间要
求和
应用
的特
点决
定移植
的程
度。
不过,
无论
如何
,移植
的
MI
Dl
et
程序
都不
能够
充分
地发
挥
Bla
ck
Be
rr
y
平
台的
优势,
如
果希望
最大
地发
挥
Bla
c
kBe
rry
平台
的优
势,
还
是需要
根据
Bla
ck
B
er
r
y
平
台的特
点重新
对应
用
进行实
现。
BlackBerry SDK下载
BlackBerry Java Plug-in for Eclipse v1.1
Java Plug-in for Eclipse Update Site
BlackBerry Web Plug-in v2.0
BlackBerry Widget SDK v1.0
BlackBerry Theme Studio v5.0
Plazmic Content Developer’s Kit v4.7
BlackBerry smartphone simulators
相关链接:
如何将MIDlet
应用移植到BlackBerry
(一)
如何将MIDlet
应用移植到BlackBerry
(二)
如何将MIDlet
应用移植到BlackBerry
(三)
如何将MIDlet
应用移植到BlackBerry
(四)
邓明轩、王恒进、王志刚
使
用
P
ersist
ent
S
t
or
e
进行存储
在
Bla
ck
Be
rr
y
平
台上
还可
以通
过
P
er
s
ist
en
tS
t
o
r
e
存储
数据,
这种
方法
可以
将对
象直接
保
存在设
备内
存中
,
需
要使
用的时
候可
以通
过
AP
I
从
设备内
存中
直接
读取
出来
,
读取
出来
看获
得的是一
个
o
bjec
t
对
象,
需要开
发人
员对
该对
象进
行强制
转换
。
相比
RunT
im
eSt
o
r
e
,
P
er
s
ist
en
tS
t
o
r
e
的好处
是可
以持
久保存
数据
,即
使设
备掉
电数据
也
不会丢
失。
不过
,使用
P
e
r
s
ist
en
t
S
t
o
r
e
要求被
保存的
数据必
须实现
P
er
s
ist
ab
le
接口。
如下
面
代码所
示,
如果
希望
将
My
Da
t
a
实例
保存
在
P
er
s
ist
en
tS
t
o
r
e
中,
M
yDa
t
a
类
需要实
现
P
er
s
ist
ab
le
接口:
public
class
MyData
implements
Persistable
{
//
其中为
MyData
的
方法和
属性定义
。
}
在
P
er
s
ist
en
tS
t
o
r
e
中保
存的
对象以
一个
长整型
的
ID
作
为标记
,
保存
或者
是获
取该
对象都
以这个
长整
型的
I
D
作
为参
数。为
了保
证所
保存
的对
象和其
它应
用保
存的
对象
不冲突
,可
以
通过
ha
s
h
算
法通
过包
名生
成一个
长整
型
ID
。
Bla
ck
Ber
ry
E
cl
ips
e
P
lu
g-i
n
环境
也提
供了一
个方
法将字
符串
转换
成长
整型
,选中
某一
行字
符串
,点
击右键
,选
择“
Co
n
v
er
t
St
r
in
g
t
o
lo
ng
”,
可以将
选中
的字
符串
转换
成长整
数。
无论用
什么
方式
生成
长整
数,对
象
ID
的定
义语
句都
类似于
以下
代码
:
public
static
long
PersistentID
=
0x815402392d453a9d
L;
定义
了
P
er
s
ist
en
t
ID
后,可
以通
过
P
er
s
ist
en
tS
t
o
r
e
的静
态方
法
g
et
P
er
s
ist
en
t
Ob
ject
获得所
保存的
持久
化对
象,
g
et
P
e
r
s
ist
en
t
Ob
ject
方法只有一
个参数
,为
保存
对象
的
ID
,本例
使用
上
面定义
的
P
er
s
ist
en
t
ID
。
获得持
外化
对象
以后
,可
以通过
该实例
的
g
et
Co
n
t
en
t
s
方法获
得真
正保
存在设
备内存
的
对象,
可以通
过
s
et
Co
n
t
en
t
s
将内存中
的对
象保
存到
持久化
对象
中。
在获
得对
象的过
程中
记
得要将
返回
的
Ob
j
ect
实例
强制转
换为
你使
用的类
。
在保存
对象
时记
得要调
用
P
ers
ist
en
tSot
r
e
的
c
omm
it
方法
完成
保存动
作。
P
ers
ist
en
tS
t
o
r
e
使用
的代码
片段如
下:
PersistentObject
persistentStore
;
persistentStore
=
PersistentStore.
getPersistentObject
(
PersistentID
);
synchronized
(
persistentStore
)
{
if
(
persistentStore
.getContents()
==
null
)
{
myData
=
new
MyData();
persistentStore
.setContents(
myData
);
persistentStore
.commit();
}
else
{
myData
=
(
MyData)
persistentStore
.getContents();
}
}
}
使
用
SQLit
e
进
行
存
储
在
Bla
ck
Be
rry
5
.
0
以
上的
平台上
提供了
对
S
ql
it
e
的
支持,
使开
发人
员可以
在
Bla
ck
Be
rry
手机上
使用
关系
型数
据库
。对于
将
MI
Dl
et
移植
到
Bl
ac
kBe
rry
上的
开发
人员
而
言,这
无疑
是
一个好
消息
,使
用关
系型
数据库
保存
数据
可以
让程
序更加
简单
有效
。
当然,
决定
是否
将数
据存
储方式
由之
前的
RMS
转变
为关系
型数
据库
,具
体要
看应用
的
规模和
数据
类型
。
一
般而
言,
如
果应
用规
模不
大,
数据类
型更
接近
树状
的文
档结构
,
则
不建
议使用
关系
型数
据库
。
反
之,
如果
应用
规模较大
,
而且需
要存
储的
数据
是大
批量的
规整
的数
据,则
使用
关系
型数
据库
比较有
利。
从具体
实现
上讲
,在
Bla
ck
Berr
y
平
台上
有
Da
t
ab
a
s
eF
a
ct
o
ry
可以用
于创
建或
者是
连接数
据库,
所创
建的
数据
库以一
个文件
的形
式保
存在
设备
中,
可
以是
设备
内存,
也可
以是媒
体卡
。
创
建
或
者
是
连
接
数
据
库
以
后
获
取
了
Da
t
ab
a
s
e
实
例
,
可
以
通
过
Da
t
ab
a
s
e
实例
的
cre
a
t
eSt
a
t
emen
t
方
法创建
一句
S
QL
语句
,通
过
S
t
a
t
emen
t
实例
的
pr
ep
ar
e
方法
准备执
行,
然
后通过该实例
的
e
x
ecut
e
方法执行。如
果是查询语句,可以
在
p
r
epa
r
e
方法执行后,通
过
g
et
Cu
r
so
r
获
得查
询结
果的
光标,
再通
过光
标操
作获
得所查
询的
内容
。
下面是
创建
或者
是连
接数
据库的
语句
:
String
dbLocation
=
"/SDCard/databases/SQLite
Demo
/"
; URI
uri
=
URI.create
(dbLocation
+
"mydb
"
);
Database
db
=
DatabaseFactory.
openOrCreate
(uri,
new
DatabaseSecurityOptions(
false
))
;
下面是
执行
查询
语句
的代
码片段
:
Statement
statement
=
_db
.createStatement(
"SELECT
*
FROM
Category"
);
statement.prepare();
Cursor
cursor
=
statement.getCursor();
下面是
查询
后遍
历结
果的
代码片
段:
Row
row;
int
id; String
nam
e;
while
(c
ur
s
or
.n
ex
t(
))
{
ro
w
=
c
ur
so
r.
ge
tR
ow
()
;
id
=
r
o
w.
ge
tI
nt
eg
er(0);
na
me
=
ro
w.
ge
tS
tr
in
g(
1)
;
}
使用完
之后
记得要
将
S
t
a
t
emen
t
实例
和
Cu
r
so
r
实例关
闭,如
:
statement.
close();
cursor.clo
se();
对于
S
QLi
t
e
的使用
,
关键
点是
S
QLi
t
e
是一
个轻
量级
的
S
QL
数
据库
,
不能
支持
所有
的
S
QL
功能。
一
方面
是在
数据格
式上只
支持
简单
的类
似
In
t
eg
er
,
T
e
xt
这
样的
类型,
另
一方面
是所
支
持的
S
QL
语句
也有
限,不
支持复
杂的
查询
操作
。
有关
S
QLi
t
e
的更
多信
息可
以在下
面的
网站
中找
到:
h
t
t
p://www
.s
ql
it
e.o
r
g
/
使用全局事件
来进行应用交
互
对于应
用通讯
,
只能
共享
数据是
不足
够的
,
在
共享
数据之
后需
要通
知相
应的
应用
,
让
目
标应用
可以
对数
据变
化进
行响应
。
Bla
ck
Be
rry
平台
提供
了事
件模型
,用
来在
不同
的应
用之间
通信
。
Bla
c
kBe
rry
上的任
何应
用程序
都可
以发
布或
者监
听全局
事件
,发
布全
局事
件的时
候需
要指
定一
个事
件
ID
号
,一
个
应用所
发布
的事
件会
被所
有监听
全局
事件
的应
用获
取,不
同的
应用
需要
通过
I
D
号判
断是
否
对该事
件进
行处
理。
另外
,
在
发送
全局
事件的
过程
中可以
同时
发送
一些
简单
的数据
,
使用
起
来会更
简单
一些
。
但
是对
于大量
的数
据,
一般
采用
的方式
是先
将数
据保
存到
特定的
共享
空间
中,然
后通
过事
件通
知目
标应用
。
首先需
要定
义一
个全
局事
件,对
于全
局事
件的
定义
,
Bla
ck
Ber
ry
有自
己的
定义
规范:
l
定义一
个
ID
变量
l
把
ID
变
量定
义为
静态
的,
从而使
得其
他的
类也
可以
引用到
l
通对包名
做
HA
S
H
产
生
ID
,使
ID
变得
独一
无二
示例代
码如
下
public
static
long
GLOBAL_ID
=
0xba4b84944bb7429eL;
定义了
全局
事件
后可
以将
该事件
发布
,
通
过把
事件
ID
传递
到
po
s
t
G
lo
ba
lE
v
en
t
(
)
方法中
,
我们可
以发
布一
个全
局事
件
Bla
ck
Be
rr
y
提
供了
有四
种不
同的方
法来
发布
一个
事件
,
简单的
方法
是只
传入事
件
I
D
不带
数据,
相对
复杂
的方
法在
发布事
件时
可以
传入
两个
整数作
为随
事件
发布
的内
容,
更
复杂
的可
以在发
布事
件时
传入
对象
作为发
布的
内容
。
开发
人员
可以根
据自
己程
序的
复杂
程序决
定使
用
什么方
法发
布一
个事
件。
最简单
的发
布事
件的
示例
代码如
下:
ApplicationManager.getApplicationManager()
.postGlobalEvent(GLOBAL_ID);
对于事
件接
受者
来说
,需
要考虑
和实
现的
关键
点如
下
·
全局监
听应
用程
序必
须要
是一个
自动
启动
应用
程序
·
监听程
序需
要有
类实
现一
个
G
lo
ba
l
E
v
en
t
List
ene
r
接口
·
监听程
序需
要添
加
G
lo
ba
lE
v
en
t
List
ener
实例
实现
Globa
lEven
t
L
ist
e
n
e
r
和添加
ClobalEve
nt
L
i
stene
r
的示例代码如下
:
class
GlobalEventListenerApp
extends
UiApplication
i
mp
le
me
nt
s
GlobalEventListener
{
public
GlobalEventListenerApp()
{
addGlobalEventListener
(
this
);
}
}
对于实
现
G
lo
ba
lE
v
en
t
List
ener
接口
的类
,
必
然实
现
ev
e
n
t
O
cc
ure
d
方法
以响
应全局
事件的
发生。
需要
注意
的一
点是
不管事
件由
谁发
布,
也不
管事件
是系
统事
件还
是程
序发布
的事件
,
只要有
事件
发生
,一
个注
册过
的
G
lo
ba
lEn
v
en
t
List
ene
r
的
ev
en
t
O
cc
ur
e
d
都会被
调用,
这意
味
着开发
人员
需要
自己
通过
事件
ID
进行
判断
,
如
果事
件
ID
属
于需
要处
理的
范围
才对事
件进
行
响应。
示例
代码
如下
:
public
void
eventOccured(
long
guid,
int
data0,
int
dat1,
Object
object0,
Object
object1
)
{
//
注意这里需要检
查事
件
ID
是不是
需要响
应的事件
。
if
(guid
==
Gl
ob
al
E
v
e
n
t
F
i
r
i
n
g
A
p
p
.GLOBAL_ID)
{
//
在这里完成事件响
应
}
}
接收推送数据
数据推送
是
Bla
ck
Be
rry
平
台的一
大优
势,
当服
务器
端有数
据更
新时
,
应
用服
务器可
以将
数据推
送到
手机上
,
不
需要
手机上
的应
用通
过轮
询的
方式检
查服
务器
上是
否有
需要更
新的
数
据。
有
关数
据推
送的
基本
架构与
服务
器的
推送
代码
,
请参
考
Bla
c
kB
er
r
y
推送
的相关
文档
,
文
小节只
描述
如何
在
MI
Dl
et
应用中
加上
手机
上侦
听推
送数据
的方
法。
应用自启动
如果希
望在
手机
端侦
听从
服务器
上推
送的
数据
,
一
般而言
需要
自动
启动
该侦
听应用
,
否
则有可
能该
侦听
应用
没有
启动,
导致
推送
数据
没有
被客户
端程
序接
收。
在
Bla
ck
B
er
ry
平台上要自动启动
一个应用程序比较简单,
可以直接通过设置完成,
在
Bla
ck
Be
rr
y
项
目中
双击
打开
“
Bla
ck
B
er
ry_
App
_De
s
cri
pt
o
r
.xm
l
”
,在
左边
“
G
en
er
al
In
f
o
rm
a
t
io
n
”
栏下方
选中
“
Aut
o
-run
o
n s
t
art
up
”就
可以
让该
项目中
的应用
在手
机启
动过
程中
自动启
动。
需要注
意的
是选
项“
Aut
o
-r
un
o
n
s
t
art
up
”只
有在
应用
类型为
“
Bla
c
kBe
rry
App
li
c
a
t
io
n
”
时可用
,也
就是
说如
果你
选择应
用类
型为
“
MI
Dl
et
”的话
就不
能使
用“
Aut
o
-r
un o
n st
art
up
”
选项。
所以需
要创
建一
个
Bla
c
kBe
rry
应用
进行
侦听
,而
不是
使用标准
的
MI
Dl
et
。
有关
Bla
ck
B
er
r
y
应
用项目
的创建
在这
里不
做详
细描
述,
需
要了
解具
体的
步骤
请参考
相关
文档。
创建
了
Bla
c
kBe
rry
项目后
首先
要考
虑应
用的
启动代
码,
Bla
ck
B
er
ry
应用
与普通
的
ja
v
a
应用一样
以
m
ai
n
方
法作为
入口。
为了更
好地
对应
用实
例进
行控制
,
这里
采用
单例模
式,
为类
P
us
he
dD
a
t
aLi
s
t
ener
创建
一
个静态
的单
例获
取方
法,
在
m
ai
n
函
数中
进行
调用
。
public
static
void
main(String[]
args)
{ PushedDataListener.
waitForSingleton
().start();
}
用
于
获
取单
例
的
静
态方法
实
现
如
下
,
一
如
普
通的单
例
获
取
方法
,
该方
法
的返
回
值
为
P
us
he
dD
a
t
aLi
s
t
ener
本
身
。在
该
方
法
中
,
使
用
了
R
un
t
im
eSt
o
r
e
将
实
例
保存
起来
,
如
果
在
Run
t
im
eS
t
o
r
e
中
已经
有实
例的话
则从
Run
t
im
eSt
o
r
e
中获取
,没
有则
创建
一个
新的实
例并
返
回。
public
static
PushedDataListener
waitForSingleton()
{
//
make
sure
this
is
a
singleton
instance
RuntimeStore
store
=
RuntimeStore.
getRuntimeStore
(); Object
o
=
store.get(
RTSID_MY_APP
);
if
(o
==
null
)
{
store.put(
RTSID_MY_APP
,
new
PushedDataListener());
return
(PushedDataListener)
store.get(
RTSID_MY_APP
);
}
else
{
return
(PushedDataListener)
o;
}
}
推送侦听
从上一
节的
启动
代码
可以
看到,
在应
用实
例得
到后调
用了
s
t
art
方法。
P
us
h
e
dD
a
t
aLi
s
t
ener
类
本
身
不
是
一
个
线
程
,
所
以
这
个
s
t
art
方
法
需
要
自
己
实
现
,
在
这
个
方
法
中
创
建
了
一
个
List
ener
Th
re
a
d
的
实例
,并
启动该
线程
。
List
ener
Th
re
a
d
实
例的
实现
主要是
创建
侦听
连接
,并
通过一
个不
结束
的循
环不
断从该
连
接中获
取服
务器
上推
送下
来的数
据。
首先需
要定
义
St
r
e
am
Co
nn
ect
io
nNot
ifi
e
r
实
例,
S
t
re
a
m
Co
nn
ect
io
nNot
ifi
e
r
用于
创建连
接。
其次需
要定
义
St
r
e
am
Co
nn
ect
io
n
和
In
putSt
re
am
,从
连接中
获取
到输
入流
,用
于侦听
数据
侦
听。
StreamConnectionNotifier
notify
=
null
; StreamConnection
stream
=
null
; InputStream
input
=
null
;
定义
St
r
e
am
Co
nn
ect
io
nN
ot
ifi
er
实例
后通
过
Co
nn
ect
o
r
的
o
pen
方法
打开
连接。
Co
nn
ect
o
r
是一个
标准
的类
,
用于连
接不同
连接
,
如
h
t
t
p
,
so
ck
et
等
。
连
接不
同网
络的时
候都是
使用
了
o
pen
方法
,在
参数
中传入
U
RL
打开
指定
的地
址。网
络的不
同类
型通
过
U
RL
参
数的不
同进
行
区分,
如
h
t
t
p
的
U
RL
以
“
h
t
t
p://
”
开
头,
而
so
ck
et
的
U
RL
是以
“
so
ck
et
:
//
”
开
头。
推
送数
据
不属于
其它
标准
的协议
,
所以它
的
U
R
L
格
式比
较特
殊,
格式
为:
“
h
t
t
p://
:
<po
rt
>
”
。
虽然
推送
的
U
RL
以
“
h
t
t
p://
”
开头
,
但是
它不
是一
个
h
t
t
p
请
求,
其
中的
“
<po
rt
>
”
为端
口号,
需要
和
服务器
推送
端约
定使
用同
一个端
口号
。
下面
是打开
边接的
代码
片段
,
其中
“
LIS
TEN
_U
R
L
”为
定义的
字符
串变
量,
值为
“
h
t
t
p://
:
9
1
1
”
,
其中
9
1
1
为约定
的端
口。
notify
=
(StreamConnectionNotifier)
Connecto
r.open
(
LISTEN_URL
);
获
得
连
接
后
需
要
将
连
接
强
制
转
换
成
St
re
am
Co
nn
ect
io
nNot
if
ier
。
获
得
St
re
am
Co
nn
ect
io
nN
ot
ifi
er
后就通
过一
个循
环不
断侦
听获取
推送
数据
。
循环的
第一
句为
not
ify
.a
cc
ept
And
Op
en
,
注意
这一句
语句执
行后
该线
程会
开始
等待,
不
再执行
,直
到有
推送
数据
到达。
推
送
数
据
到
达
后
ac
c
ept
And
Op
en
方
法
返
回
一
个
St
re
am
Co
nn
ect
io
n
实
例
,
通
过
St
re
am
Co
nn
ect
io
n
实例的
o
penI
np
ut
St
re
am
方法
可以
获得输
入流
,然
后通
过输
入流获
得推
送
数据。
注意操
作完
成后
需要
将输
入流
和
St
re
am
Co
nn
ect
io
n
关闭,
关闭
后重
新开
始侦
听,
等
待下
一个推
送数
据。
侦听的
代码
片段
如下
:
for
(;;)
{
stream
=
notify.acceptAndOpen();
input
=
stream.openInputStream();
//
在这里通
过对
input
的操
作获得推
送数据
input.close(); stream.close(); stream
=
null
;
}
另外需
要注
意的
是异
常处
理,
因为
连接
的建
立和
输入
流的处
理可
能会
因为
一些
原因抛
出
异常
。
一种方法是在循环内处
理
异常,处理完了继续循
环
,
但是这无
法
对
C
o
nn
ect
o
r
.o
pen
方法进
行处
理。
所以
需要
在循环
外对
异常
进行
处理
,
将
Co
nn
ect
o
r
.o
pen
包含
进来,
本文
的例
子就是
使用
这种
方法
。
但
是,
实际
而言
这种处
理方
式也有
问题
,
当输入
流处
理有问
题的时
候
会跳出
循环
,不
再侦
听推
送数据
。
最终建
议的
方法
是建
立两
重循环
,
在
两重
循环
都加
上异常
捕获
。
外
层循
环中
的异常
处理
负责处
理
Co
nn
ect
o
r
.o
pen
的异常
,出
现异
常的
话处
理后重
新通
过
Co
nn
ect
o
r
.o
pen
打
开连
接。
内层循
环对
输入
流异
常进
行处理
,
处
理后
继续
侦听
数据,
而不
需要
重新
通过
Co
nn
ect
o
r
.o
pen
打开连接
。
具
体代
码请
参考
开发环
境附
带的
样例
。
本文
为简化
代码
没有
采用
双重
循环的方式
。
侦听程序与主
程序的交
互
获取侦
听数
据后
需要
做的
工作是
通知
主程
序有
新数
据到达
,由
主程
序对
数据
进行处理
。
因为侦
听程
序为
后台
程序
,
不负
责界
面更
新等
操作
,
界面
更新
的操
作由
MI
Dl
e
t
主程序
完成
。
可以看
到关
键是
作为
侦听
程序
的
Bla
ck
Be
rr
y
应
用与
作为主
程序
的
MI
Dl
et
如何
交互,
这可
以
使用上
一章
节介
绍的
方法
,通
过
G
lo
ba
lE
v
en
t
通
知主
程序,
然后
将数
据写
入共
享数据
中。
主
程序在
接收
到事
件通
知后
共享数
据中
获得
推送
数据
再进行
数据
处理
和界
面更
新处理
。
具体
方
法不再
详细
描述
。
推送侦听的完
整代
码
下面是
推送
数据
侦听
的完
整代码
,不
包括
应用
交互
部分:
package
cn.searb;
import
java.io.IOException;
import
java.io.InputStream;
import
javax.microedition.io.Connector;
import
javax.microedition.io
.StreamConnection;
import
javax.microedition.io.StreamConnectionNotifier;
import
net.rim.device.api.system.RuntimeStore;
import
net.rim.device.api.ui.UiApplication;
public
class
PushedDataListener
extends
UiApplication
{
public
static
final
long
RTSID_MY_APP
=
0x68b31bd292413108L;
private
static
final
String
LISTEN_URL
=
"
ht
tp
:/
/:
91
1"
;
//
th
e
li
st
en port
private
ListenerThread
myThread
;
public
static
void
main(String[]
args)
{ PushedDataListener.
waitForSingleton
().start();
}
public
PushedDataLi
stener()
{
myThread
=
new
ListenerThread();
}
public
static
PushedDataListener
waitForSingleton()
{
//
make
sure
this
is
a
singleton
instance
RuntimeStore
store
=
RuntimeStore.
getRuntimeStore
(); Object
o
=
store.get(
RTSID_MY_APP
);
if
(o
==
nu
ll
)
{
store.put(
RTSID_MY_APP
,
new
PushedDataListener());
return
(PushedDataListener)
store.get(
RTSID_MY_APP
);
}
else
{
return
(PushedDataListener)
o;
}
}
public
void
start()
{
invokeLater(
new
Runnable()
{
public
void
run()
{
myThre
ad
.start();
}
});
this
.enterEventDispatcher();
}
class
ListenerThread
extends
Thread
{
public
void
run()
{
System.
out
.println(
"DemoOA
BackGroundThread
--
running"
); StreamConnectionNotifier
notify
=
null
;
StreamConnection
stream
=
null
; InputStream
input
=
null
;
try
{
sleep
(1000);
}
catch
(Exception
e)
{
}
try
{
notify
=
(StreamConnectionNotifier) Connector.open
(
LISTEN_URL
);
for
(;;)
{
stream
=
notify.acceptAndOpen();
input
=
stream.openInput
Stream();
//
stream.close();
stream
=
null
;
}
}
catch
(IOException
e)
{ System.
err
.println(e.toString());
}
finally
{
try
{
if
(stream
!=
null
)
{
stream.close();
}
}
catch
(Exception
ex)
{
}
try
{
if
(notify
!=
null
)
{
notify.close();
}
}
catch
(Exception
ex)
{
}
}
}
}
}
小结
通过本
文的
介绍
读者
可以
发现,
将
MI
Dl
et
程序
移植
到
Bla
ck
Be
rr
y
上
并不
困难
,同时
开
发人员
也可
以根
据项
目的
时间要
求和
应用
的特
点决
定移植
的程
度。
不过,
无论
如何
,移植
的
MI
Dl
et
程序
都不
能够
充分
地发
挥
Bla
ck
Be
rr
y
平
台的
优势,
如
果希望
最大
地发
挥
Bla
c
kBe
rry
平台
的优
势,
还
是需要
根据
Bla
ck
B
er
r
y
平
台的特
点重新
对应
用
进行实
现。
BlackBerry Java Plug-in for Eclipse v1.1
Java Plug-in for Eclipse Update Site
BlackBerry Web Plug-in v2.0
BlackBerry Widget SDK v1.0
BlackBerry Theme Studio v5.0
Plazmic Content Developer’s Kit v4.7
BlackBerry smartphone simulators
相关链接:
如何将MIDlet
应用移植到BlackBerry
(一)
如何将MIDlet
应用移植到BlackBerry
(二)
如何将MIDlet
应用移植到BlackBerry
(三)
如何将MIDlet
应用移植到BlackBerry
(四)
相关文章推荐
- 如何将MIDlet应用移植到BlackBerry(一)
- 如何将MIDlet应用移植到BlackBerry(二)
- 如何将MIDlet应用移植到BlackBerry(三)
- 如何快速把安卓应用移植到BlackBerry 10上
- 如何快速把安卓应用移植到BlackBerry 10上
- 一个J2ME的应用移植到BlackBerry上,如何处理按键响应(以及如何映射左右软键)
- 如何将Android应用移植到BlackBerry PlayBook上。
- Qt应用如何移植到Windows CE系统上
- 问题:如何qDebug自己开发的运行在BlackBerry 10的Work Space中的企业应用呢?
- iPhone5来了,如何移植之前的原生应用和cocos2d游戏
- FT5X06 如何应用在10寸电容屏(linux-3.5电容屏驱动简析&移植10寸电容屏驱动到Android4.2) (by liukun321咕唧咕唧)
- iOS: 分步演示如何将iPhone应用移植至iPad平台
- J2ME MIDlet开发人员的第一个BlackBerry应用
- [视频]微软展示如何轻松移植iOS/Android应用到Win10上
- 开发者分步演示如何将iPhone应用移植至iPad平台
- FT5X06 如何应用在10寸电容屏(linux-3.5电容屏驱动简析&移植10寸电容屏驱动到Android4.2) (by liukun321咕唧咕唧)
- BlackBerry 应用和 MIDlet 之间的交互
- 如何把iOS 应用移植到Android?
- 如何从你的BlackBerry应用中启动浏览器
- J2ME MIDlet开发人员的第一个BlackBerry应用