2008-07-16
试翻译Openbasemovil-core 2.0 Developers Guide
为了对openbasemovil-core库有一个全面的认识,我翻译了它的开发者指南,翻译得不算太好,但都是我的个人理解,希望大家指正。
OpenBase Movil Core 开发指南
---------------------------------------------------------------
版本号: 1.0
作者: Narciso Cerezo
翻译: iwinyeah
索引
1. 序言 ..................................................... 3
2. 核心包简介 ............................................... 5
2.1 事件管理 ................................................ 5
2.1.1 进度事件 .............................................. 5
2.1.2 语言变化事件 .......................................... 5
2.1.3 后台任务 .............................................. 5
2.1.4 登记事件监听器 ........................................ 6
2.1.5 创造新事件 ............................................ 6
2.2 任务管理 ................................................ 7
2.3 文件系统 ................................................ 7
2.4 序列化 .................................................. 8
2.5 日志 .................................................... 9
2.6 数学库 ................................................. 10
2.6.1 为某一特定区域设置浮点数 ............................. 10
2.7 MVC模式 ................................................ 11
2.7.1 视图 ................................................. 11
2.7.1.1 行动 ............................................... 11
2.7.1.2 抽象视图 ........................................... 11
2.7.2 控制器 ............................................... 12
2.7.3 帮助 ................................................. 13
2.8 国际化 ................................................. 14
2.9 压缩 ................................................... 14
2.10 应用程序框架 .......................................... 15
2.9.1 应程序管理器 ......................................... 15
2.11 其他工具 .............................................. 15
2.11.1 校验码 .............................................. 15
2.10.2 加密 ................................................ 15
2.11.3 信息摘要算法(MD5) ................................... 15
2.11.4 设备扩展信息 ........................................ 16
2.11.5 属性文件 ............................................ 16
2.11.6 简单的缓存系统 ...................................... 16
2.11.7 本地化格式 .......................................... 17
2.11.8 工具 ................................................ 18
2.11.8.1 安全的内存申请 .................................... 18
2.11.8.2 数组式Vector ...................................... 18
2.11.8.3 对象相等性 ........................................ 18
2.11.8.4 重复字符 .......................................... 18
2.11.8.5 幂(乘方)计算 ...................................... 18
2.11.8.6 字符串分析 ........................................ 18
2.11.8.7 自动分行 .......................................... 18
3.l 版权 ................................................... 19
3.1 保证 ................................................... 19
1. 序言
Openbasemovil-core库,是Openbasemovil中最基本的库,所有其他的openbasemovil库,从数据库引擎到脚本引擎,都依赖于这个库。
它为其它类提供一些公共的服务,包括很多没有在JavaME中实现的类。
• 事件管理
这是一个集中式事件管理器,它可以处理不同类型的事件,该管理器允许多个监听器监听全局性事件或者特定类型的事件(通过自定义事件或者事件过滤)。
• 任务管理
控制所有活动的线程,它们之间的交互,终止等。
• 文件系统
它使用记录存储系统(RMS)来模拟实现文件系统,FileOutputStream和RandomAccessFileInputStream。
• 序列化
该串行接口是替换在JavaMe中没有实现的java.io.serializable,即允许任何类型的对象从流中序列化和反序列化。它也包含复杂对象序列化/反序列化,包括复杂的
Tree类对象,任何的混合型Hashtables, Vector, 和其他类对象。
• 日志
一个基本的日志应用程序接口,与Jakarta公共日志软件包类似,具有可插拔的接口,可用于调试和生产环境。
• 数学
包含浮点数计算类,替换了在JavaME CLDC 1.0 中未实现的浮点/双精度浮点类。
• MVC模式
包含基本的一个模型-视图-控制器系统,可处理新线程中的进度命令、高级的类Action类,集成Help管理等。
• 国际化
通过使用资源文件,让您的应用程序支持多种语言。语言是自动侦测的,但可以动态手动改变。它也具有可插拔的机构,这样你就可以使用任何贮存类型的资源而不局限于属性文件了。它同时处理日期、数字、货币的格式等。
• 压缩
一个改编的较短版本的jzlib库,改编自zlib。
• 其他工具:
* CRC校验(使用Adler32算法)。
* 对称加密与Blowfish(http://www.bouncycastle.org)。
* 信息摘要算法MD5(http://www.bouncycastle.org)。
* 设备扩展信息
* 支持读和写的属性文件。
* 简单的缓存系统,使用LRU抛弃策略。
2. Openbasemovil-core库简述
2.1 事件管理
在每一个应用程序中,需要进行长时间的过程中必须始终通知用户有关任务的进展情况。只有这样,使用者才能肯定应用程序仍然在良好的状态下运行。
它最初只是一个事件管理系统的驱动器。它联结发出进度事件的非用户界面库和终端应用程序,后者监听事件并向使用者显示当前进度。
但现在它向前演化了,还充当了在生产者和监听器之间传输各种类型事件的枢纽。
其中关键的类bm.core.event.event,即代表了事件本身,但也有一些静态方法用于控制监听器的登记、事件的调度等。
另一个关键的类bm.core.event.eventlistener,如果类要具有监听事件的能力,它就是一个必须实现的接口。
core库已经为一些情况预定义了某些事件类型以便于控制,并且它还有一些扩展了其属性的子类。
2.1.1 进度事件
进度事件是一个特殊类型的事件,是事件的子类:bm.core.event.progressevent。进度事件类有一些属性用于表达任务的进展情况,例如类型(定步长|不定步长)、最大值、当前值、标签等。
进度事件的ID为1。
例子:
// 创建一个事件并指定其事件源
final ProgressEvent event = new ProgressEvent( this );
event.setAnimate( true ); // 事件没有固定的步长
event.setTitle( "Some task" );
event.setMessage( "Please, wait..." );
event.dispatch(); // 调度该事件
2.1.2 语言更改事件
语言和资源由bm.core.ResourceManager负责管理。当使用者改变语言时,监听器将收到该事件,这样它们就可以丢弃原先缓存的语言信息并装入新的资源了。
语言改变事件没有特定的子类,它被的ID为2。
更多关于国际化和资源管理的资料,可以参考第2.8节。
2.1.3 后台任务
在openbasemovil库中,许多类会产生进度事件,它们将会依次更新进度显示视图,如果你执行的是一个后台任务,这显然不是一种合适的行为。
这时你可以创建一个ControlledTask的子类,并将它设为后台任务,这样,事件管理器将筛选出进度事件,后台事件将被丢弃。
更多关于ControlledTask的资料,请参考第2.2节。
例子:
// 创建一个控制任务
public class MyBackgroundTask extends ControlledTask
{
public MyBackgroundTask()
{
super( "MyBackgroundTask", true ); // 任务名称,后台任务标志
}
}
2.1.4 登记监听器以监听事件
你只需要实现bm.core.event.EventListener接口就可以监听任何类型的事件。
该接口只定义了一个方法:void handleEvent(Event event);
同时可以有多个监听器监听同一类型的事件,你也可以将你的监听器登记为全局监听器(监听全部的事件而无论事件是什么类型)。
监听器保存在一个有序的列表中(以Vector实现),并且按它们登记的先后顺序来调度。
事件类可能被某一监听器标志为消灭状态,一旦发生这种情况,事件调度链将被打断,后续监听器将不会监听到此事件。
消灭标志也会在调度完成后被自动置位,这样事件对象就可以被重新使用了。
例子:
public class MyListener implements EventListener
{
public MyListener()
{
// 你可以在任何位置登记监听器
// 放在构建函数中只是为了方便举例
// 监听语言改变事件
Event.register( this, Event.LANGUAGE_CHANGE );
}
public void handleEvent( Event event )
{
// 当事件发生时作出响应
}
public void someMethod()
}
}
2.1.5 创建新事件
当然,为适应实际需要,你可以在事件系统中使用任何类型的事件。
如果你的事件不需要其他属性,你可以为事件类指定一个自定义事件类型ID,直接使用事件类,如果你需要其它属性,你可以创建事件的子类。
但无论如何,你必须自定义事件类型ID,该ID应大于10000,低于10000的值保留为这个类以用OpenBaseMovil的其他类使用。
事件类型ID没有特别的登记方法,当监听器登记一个未存在的事件类型时,该类型将会被自动创建。
2.2 任务管理
我们建议你总是在新线程里处理用户交互动作(命令),这样当命令被处理时,设备能保持对用户动作的快速反应。
线程还在很多其他情形下非常有用,例如需要在后台做处理工作而前台保持与用户的交互作用时。
如果你不仔细规划你的线程,将可能导致线程死锁,或造成协同问题。
并且当你需要退出应用时,你需要一些方法通知所有运作中的线程停止以便完全退出。
为了处理这种情况,以及在后台处理进度事件,我们创建了ControlledTask类。
例子:
// 新建一个ControlledTask对象
public class MyControlledTask extends ControlledTask
{
public MyControlledTask()
{
super( "MyControlledTask", false ); // 新建一个前台线程
}
protected void task()
{
// 一个任务可以运行后立即终目,也可以运行直到收到终止通知
// 当cancel属性为真时,任务被通知终止
// 它必须自行终止
while( !cancel )
{
// 执行任务
}
}
protected void die()
{
// 在CLDC 1.0中,当线程正常地完成后,这个方法将在被调用
// 这是一个最好的调用方式;
// 不正常的调用方式,譬如任务在读取输入流时死锁,
// 关闭输入流将解除死锁并终止线程。
}
}
例子:
// 取消所有任务
ControlledTask.cancelAll();
这个方法在CLDC 1.0和CLDC 1.1有不同实现,因为第一个没有interrupt()方法。任务正常完成后如果没有终止,这个方法将在通知终止后被调用。
2.3 文件系统
文件系统包含有两个备受称赞的类,实现了一个与FileOutputStream类似的输出流,它基于记录贮存系统(RMS)而不是正常的文件,一个有随机读取能力的输入流(读取的目标“文件”是与其配对使用的上述输出流)。
这个包很多情况下是十分有用的,它在基于记录贮存系统(RSM)对真实文件进行了模拟,无须特别的权限,无须实现文件API,而且它使你可以在使用很小的内存就可以无缝地贮存比较大的文件。
输出流的名称为bm.core.fs.SequentialFileOutputStream,这个类使用记录贮存系统(RSM)并将要构成文件的数据分成小块,每一小块在RMS中映射为一个记录。默认地,它每小块的长度为5K,但你可以在构建时指定块的大小。
输入流的名称为bm.core.fs.RandomAccessInputStream,它是一个简单的输入流,却是从与它配对使用的输出流写入的RMS中读取记录,特别的是它具有seek()方法,具有移动流输入位置的能力。
例子:
// 读写文件
SequentialFileOutputStream os = null;
RandomAccessInputStream is = null;
try
{
// 新建一个文件并写入1000字节
os = new SequentialFileOutputStream( "myfile" );
for( int i = 0; i < 1000; i++ )
{
os.write( 1 );
}
os.close();
// 打开文件
is = new RandomAccessInputStream( "myfile" );
// 跳过前500字节
is.seek( 500 );
// 读取后500字节
for( int i = 0; i < 500; i++ )
{
is.read();
}
is.close();
}
catch( Exception e )
{
e.printStackTrace();
}
finally
{
if( os != null ) try{ os.close() } catch( Exception e ){}
if( is != null ) try{ is.close() } catch( Exception e ){}
}
2.4 串行化
串化化是一个在JavaME中缺少的关键概念,而它在OpenBaseMovil框架在被广泛使用。
与JavaSE中原来的串行化接口不同,它不只是建造器:它有两个方法,serialize和deserialize,理由很简单,在JavaME中没有反射或者其它什么机制可以使一个类知道什么类已经装入。
使用bm.core.io.Serializable接口,对象自定义了一个通过输入输出流读写它们自身的方法。
而通过bm.core.io.Serializable接口,对象定义了它们如何将自己的特性写入或从流中恢复。并且其他对象可以统一的方法处理他们,例如使用库所提供的bm.core.io.SerializerOutputStream和bm.core.io.SerializerInputStream。
在bm.core.io.Serializable接口中还定义了getName()方法,当使用serializer流的writeObject/readObject方法实现对象serialized/deserialized时,它可返回该类的名字。这在使用混淆器时的一个安全的机制,如何不使用它将会无法读回之前序列化的一个对象。
例子:
// 创建一个序列化对象
public class MySerializableClass implements Serializable
{
private String string1;
private int int1;
private Short short1;
private byte[] data;
public void getName()
{
return "MySerializableClass";
}
public void serialize( final SerializerOutputStream out ) throws SerializationException
{
out.writeByte( (byte) 1 ); // 建议包含一个版本号
out.writeString( string1 );
out.writeString( int1 );
out.writeShort( short1 );
out.writeBlob( data );
}
public void deserialize( final SerializerInputStream in )
{
in.readByte(); // 忽略版本号.如果版本号不同,你也许要处理一下
string1 = in.readString();
int1 = in.readInt();
short1 = in.readNullableShort();
data = in.readBlob();
}
}
例子:
// 使用序列流serializer streams
// 序列化工厂的初始化应的应用启动时完成
// We should do MySerializableClass.class, but that does not work on CLDC 1.0
SerializerFactory.register( "MySerializableCass", new MySerializableCass().getClass() );
final Vector list = new Vector( 3 );
final Hashtable map = new Hashtable( 1 );
list.addElement( new MySerializableClass() );
list.addElement( new MySerializableClass() );
list.addElement( new MySerializableClass() );
map.put( "key", list );
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SerializerOutputStream out = new SerializerOutputStream( baos );
out.writeObject( list );
out.close();
ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
SerializerInputStream in = new SerializerInputStream( bais );
list = in.readObject();
in.close();
serializer流可以读或写对象的nullable或者非nullable的树,无论该树以任何层次以任何形式巢化,而唯一的限制是该树的全部元素必须是一种原始类型(包括字节阵列),Vectors, Hastables 或序列化对象.
2.5 日志
该日志系统以一个优雅而有效率的方式将日志消息到应用到您的代码中。
它有一个模仿Jakarta通用日志包,其中的差异要通过字符串而不是一个类来创建日志,这是由于CLDC1.0缺少了NoClassDefFoundException而造成的.
日志接口让您可以在编译时插入不同的实现,因此,您可以通过控制台显示日志信息,将他们写入一个文件或者干脆忽略它们。
通过这种方式,您可以为您的应用建立不同的版本,典型地,你可以将它分开成开发版正式版.
例子:
// 使用日志系统
import bm.core.log.*;
public class MyClass
{
private static final Log log = LogFactory.getLog( "MyClass" );
public void foo()
{
log.info( "foo method" );
log.debug( "this is a debug message" );
}
}
2.6 数学
虽然cldc1.1附带的浮点支持,然而还有很多使用cldc1.0的手机,它们不支持浮动类型也没有双精度类型。
bm.core.math.fixedpoint的创建就是为了在使用cldc1.0的手机提供浮点数支持. 它也有一些其他公用方法,例如根据区域设置显示适当金额字符串及其单位。
Fixedpoint类内部使用了一个长整数保存数值,并使用短整型指示其精度。因此,value * 10precision = floating point value 浮点值。
您要时刻记住,与Java语言中的其他的数值对象一样,Fixedpoint是不可变对象。
当然,Fixedpoint也是可序列化的.
例子:
FixedPoint fp = FixedPoint.ONE; // FixedPoint.ONE 是一个有用的常量用于表示浮点数 1.0
FixedPoint fp1 = fp.mult( FixedPoint.ZERO ); // FixedPoint.ZERO 用于表示浮点数 0.0
System.out.println( fp1.toString() ); // 将打印出 0
FixedPoint fp10 = FixedPoint.parse( "10" );
FixedPoint fp10_325 = FixedPoint.parse( "10.325", '.' );
// 以下若使用西班牙区域将打印10,33€ ,而使用美国区域将打印$10.33
System.out.println( fp10_325.toMoneyString() );
System.out.println( fp10_325.div( fp10 ).toString() ); // 将打印: 1.0325
System.out.println( fp10_325.toString() ); // 将打印: 10.325 因为FixedPoints是不可变的
2.6.1 将Fixedpoint配置为某一特定地区
与本核心库一起提供的西班牙语(西班牙)和英语(美国)资源档案已经界定了Fixedpoint的行为。以下配置是用来规定Fixedpoints是如何实现浮点数和字符串互换的.
# A single character to separate integer from decimals
fixedPoint.decimalSeparator
# A grouping separator to use for toMoneyString
fixedPoint.groupingSeparator
# The money symbol or character
fixedPoint.moneySimbol
# If the symbol comes before or after the quantity
fixedPoint.moneySimbolAfter
2.7 MVC 模型
您可以使用核心库中的MVC模型来建造您的应用.
该库提供了一个抽象控制器,它处理应用发出的(响应玩家动作)的命令,为该命令创建一个新线程来处理它.
其中,它还会拦截一些事件,例如帮助请求.
它还提供了一个抽象的视图,该视图有一些有用的方法,通过扩展它您可以从中得到不少的益处.
控制器和视图都有较少的接口, 因此你可以总是使用接口而不是它们的子类,但是我们不推荐这样使用,除非在很特殊的情况下。
2.7.1 视图
与将应用的视图作为Canvas、Form或其它MIDP类的子类相反,视图接口允许你从真正实现中抽象出来,这样您就可以无缝地改变实现。
一个视图必须有一个id,一个中应用中唯一的数值的标识符。这个Id使控制器里可以很快地找到特定的视图,加快switch语句中的速度。
视图可以拥有一个呼叫者视图,这样视图就可以很简单地切换回呼叫者视图。
当你从视图中返回呼叫者视图时(使用goBack 方法),那些release()方法将被调用,这样它就可以释放它可能持有任何资源。请注意,视图流向前时release()方法不会被调用,只有向后返回时才会被调用。
视图也可能有附件。这些附件可能是任何类型的对象,并且可以通过视图流向后取得。这个机制可用于保持一组页面会话的状态。例如,你从客户列表中选择了一个客户,然后你转到客户明细信息页,将该客户与该页关联起来,在客户明细信息页面,你有一些相对于该客户的动作,如呼叫该客户、为该客户做一个订单等,所有后续的动作都会参考该页关联的客户。
2.7.1.1 动作
行动是一种超越传统MIDP命令的先进的概念,但与之非常类似。事实上,行动会被翻译成命令。
行动可以宣告,添加视图,并且可以启用或停用。您可以添加一个未启用的行动,稍后再激活它,和它相关的命令也会将被添加到的视图中。
在openbasemovil-util库中,行动在视图设计中的一个有用的元素。通过这种方式,可将视图宣告在一个XML文件中,并以一种简单的方式来定义它们的功能。
2.7.1.2 抽象视图
这个类实现了接口View中所有的常用方法,从而成为一个可为特定视图提供完美服务的超类。但它也有一些静态的方法为整个openbasemovil库和其它库使用,所以你应该尊重它所实现的模型,即使您不创建它的子类。
它的所有实现是行动和附件所必需的。
但它也执行其他非常重要的任务:
• 保持目前显示的视图
由于我们所使用的视图,我们不能依靠Display对象从MIDP的获得目前显示的视图。因此,它使用一个静态成员,当每次调用一个view的show()方法时,该静态变量将被更新。
如果您的视图不是抽象视图的子类,你在show()方法中就需要调用setcurrent()方法了。
• 控制闲置时间的应用
每当当前视图中发生变化,或者用户执行了一些动作,它即时将一个静态计数器置0。这样,您就可以检查应用与玩家有多久没有互动了,这是非常有用的,例如,锁定应用,并要求玩家输入一个PIN。
• 当视图被释放时通知控制器
抽象视图的子类可以而且应该实现释放方法release()以释放资源。但对于一些普遍而复杂视图,例如openbasemovil-util库中的一些实现,有时不能完成释放这些资源。这些释放操作就下放到控制器的回调方法onRelase()来完成。抽象视图在其release()方法中默认地调用其视图控制器的onRelase(),它还会卸下所有的附件(对象)。
• 处理某些型号手机的一些显示错误
不同型号的手机之间的javame实现有时是有巨大的分别的。目前最好的javame实现是索爱的jp7和jp8平台,其次是诺基亚。甚至在同一平台下不同固件的机器之间也有不同。诺基亚的虚拟机在任务管理方面是最强大的,但随后发布的索爱jp7则更快但存在一些错误。
2.7.2 控制器
控制器是MVC框架的其中一个重要的部分。控制器从当前视图中得到原始的行动事件,执行一些行动并且也许显示另一个视图。
控制器应该封装决定显示哪个视图的代码,并充当将模型取得数据供给视图的管道。
控制器仅有两个方法:
/**
* Handle an event.
*
* @param event event to handle
*/
void handle( ControllerEvent event );
/**
* When a view is released.
* @param view view released
*/
void onRelease( View view );
handle()方法是最重要的,它接收的ControllerEvent具有执行相应任务全部需要的信息。
目前ControllerEvent并不是Event的子类,但在2.0 版本将会改变。
ControllerEvent有一个事件码,它是一个整数,指示玩家选择的是哪个行动;事件源指示产生行动的源视图;一个索引用于在源视图是一个列表时指示玩家的选择。
它也为全局性的行动定义了一些具体的事件码。这些事件码被保留:
public static final int EXIT = 10000;
/**
* Standard event for help.
*/
public static final int HELP = 10001;
/**
* Standard event for back.
*/
public static final int BACK = 10002;
/**
* Standard event for accept.
*/
public static final int ACCEPT = 10003;
/**
* Standard event for cancel.
*/
public static final int CANCEL = 10004;
/**
* Standard event for stop.
*/
public static final int STOP = 10005;
/**
* Standard event for home.
*/
public static final int HOME = 10006;
/**
* Standard event for list item selection on list views.
*/
public static final int LIST_ITEM = 10007;
如你所见,它们非常类似于MIDP中的命令类,但是也增加了一些功能。
其中的onRelease()方法,已经在前面有所提及,将会被视图回调以释放其资源。
2.7.3 帮助
bm.core.HelpAssisted接口,由视图使用,用于指示有上下文帮助可以使用。
你可以使用这个标记自动给视图添加一个帮助行动。
抽象控制器AbstractController拦截帮助事件ControllerEvents,如果视图实现了HelpAssisted,它将为视图查找帮助文本并显示。
为查找并且显示帮助文本,抽象控制器AbstractController(通过ControllerTask的子类ControlledTask)将会使用HelpView类。
HelpView只是一个文本显示视图,你甚至可以为了全屏显示一份文本的目的而使用它。但它具有为一个规定了HelpAssisted项查找帮助的能力。
为了做到这一点,它使用了资源供给器ResourceProvider。这个接口允许HelpView使用一个给定的ID请求帮助而无须关心如何得到该信息。
默认地,它使用帮助资源供给器ResourceHelpProvider。帮助资源供给器ResourceHelpProvider将使用资源管理器ResourceManager尝试依次查找适于当前的语言的(你打包在你的jar文件内的一些文件)的资源。 例如,一个帮助的项目返回的帮助Id为"MainView",目前默认的语言是en_US,那它将查找资源文件"MainView.en_US.txt", 如果不存在它将尝试"MainView.en.txt"。
通过使用HelpProvider接口,你可以创建你的帮助供给器。OpenBaseMovil商业应用通常使用索引或者数据库表实现帮助。这样就可以创建更小的jar文件,并且可以动态地更新帮助而无须重新安装应用了。
2.8 国际化
虽然已有专门用于国际化的JSR,但目前支持这个JSR的设备仍然很少。如果您想要在更广泛的设备上支持国际化,你就不能依靠他们。
这就是我们建立国际化的框架的原因,该框由其中的资源管理器ResourceManager类和资源供给器ResourceProviders类组成。
资源管理器ResourceManager侦测手机所使用的语言,并允许您手动设定所使用的语言。如果你这样做,ResourceManager通知核心类,譬如FixedPoint或HelpView,并触发LANGUAGE_CHANGE事件,这使任何在侦听该事件的对象得到语言变化的通知。
资源管理器ResourceManager基本上是通过使用资源关键字调用getResource()方法。ResourceManager会要求配置好的资源供给器ResourceProviders以当前的区域设置返回指定关键字的资源。如果关键字没有找到,那么将返回关键字。这消除了NPE?,使您清楚知道您的应用丢失了一些资源。
资源供给器ResourceProviders是可插拔的组件,它可以添加到ResourceManager中,他们实际的从各种存储系统中读取资源的类。
默认地,ResourceManager会自动配置属性供给器PropertyResourceProvider,它们将会使用前述帮助机制,在打包在JAR文件中的资源组中查找适当的属性。
BaseMovil的商业应用通常会使用索引来替代,因为他们不必将资源打包在jar文件中并且可以进行重新而无须再重新安装该应用程序。
2.9 压缩
bm.core.zlib包取自Jzlib项目,只是略有改动,以便尽量减少压缩算法中的内存消耗。
该库通过ZInputStream和ZOutputStream类使用,信息的解压和压缩被隐藏在流中,就样应用就可以即时透明地使用该库。
例子:使用ZInputStream、ZOutputStream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// 其他层次通常会抛出OutOfMemoryError
ZOutputStream zos = new ZOutputStream( baos, Zstream.Z_BEST_SPEED );
zos.write( 1 );
zos.flush();
zos.close();
ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );
ZInputStream zis = new ZInputStream( bais );
int c = zis.read();
zis.close();
2.10 应用框架
本库的被设计为不仅用于JavaME CLDC,而且也可用于其他平台。应用框架增加了用来隐藏的平台底层细节的层。
应用Application对象ApplicationManager,CommandFactory和global timer中的一个接入点:
• 对于具体的实现来说,ApplicationManager是一个它提供系统访问的接口。
• CommandFactory提供访问应用程序命令的接入点。这是非常有用的:通过它所有视图可循环再用命令对象,这样您就可以创建一个单一标准的命令实例或者应用程序所用的其它命令。
• 全局计时器global timer提供一个单一的计时器,以调度应用的TimerTasks。
2.10.1 应用管理器 ApplicationManager
openbasemovil-util库提供了一个MIDP的ApplicationManager的实现。
2.11 其它工具
2.11.1 CRC 校验
Adler32类是用于执行快速的CRC计算,以确保写入和读出的数据是一致的。
2.11.2 Encryption 加密
加密库是采用了Blowfish算法,源自The Legion of the Bouncy Castle。
例子:使用Blowfish算法加密和解密
// 加密一个字符串
Blowfish cipher = new Blowfish();
cipher.init( true, "MyPassword".getBytes() );
final byte[] encrypted = cipher.encrypt( "Text to chiper" ); // 默认字符串是UTF-8格式的
// 加密字节数组
final byte[] source = new byte[10];
for( int i = 0; i < 10; i++ )
{
source[i] = (byte) i;
}
final byte[] encrypted2 = cipher.encrypt( source );
// 解密字符串
Blowfish decipher = new Blowfish();
decipher.init( false, "MyPassword".getBytes() );
final String text = decipher.decryptString( encrypted );
// 解密字节数组
final byte[] block = decipher.decrypt( encrypted2 );
2.11.3 信息摘要
信息摘要(安全散列secure hash)采用了MD5算法,源自The Legion of the Bouncy Castle。
例子:为安全散列使用MD5
// 将密码进行摘要入安全散列
MD5Digest md5 = new MD5Digest();
final byte[] data = password.getBytes();
md5.update( data, 0, data.length );
// 字节数组用于保存摘要
final byte[] digest = new byte[16];
md5.doFinal( digest, 0 );
// 随后你就可以将玩家的输入摘要与之前摘要出的安全散列进行对比
2.11.4 设备扩展信息
DeviceInfo类提供正在运行应用设备的有用信息。
部分的代码来自TastePhone项目,主要是评估设备速度部分的代码。
DeviceInfo类检查一些非常普通的缺陷是否存在于正在运行的设备中,并且直接提供设备的品牌、模块、操作系统等等。
这些信息是从各种各样的来源中获得的,部分来源于系统属性、部分来源于User-Agent头部信息、部分由内置Web浏览器送出。User-Agent头部信息只在应用通过OTA方式安装并应用一个服务,将头部信息置入JAD文件中的User-Agent属性来得到。
2.11.5 属性文件支持
属性Properties在JavaSE中是非常有名的类,它是Hashtable的子类,其中的关键字和值都是字符串,并且可以众所周知的方式写入或从流中读出。
但令人遗憾,JavaME没有属性类,因此我们理解并且以JavaSE相同的形式实现了这个类。
2.11.6 简易的缓存系统
应用能在很多情况下受益于一个高速缓存系统以提高重复存取的速度。SimpleCache类以LRU方式简单而快速地完成高速缓存操作。
例子:使用SimpleCache提高速度
public class ItsHardToReadMyItems
{
private SimpleCache cache = new SimpleCache( 2 ); // 最多缓存两项
public Object get( final Object key )
{
Object object = cache.get( key );
if( object == null )
{
object = ... ; // 将会花费较长的时间
cache.add( key, object ); // 将它加入缓存备用
}
return object;
}
public Object set( final Object key, final Object value )
{
... ; // 保存对象
cache.add( key, object ); // 更新缓存的对象
}
public void remove( final Object key )
{
...; // 删除对象
cache.remove( key ); // 从缓存中清除
}
}
// 其他使用该缓存的类
....
ItsHardToReadMyItems hard = new ItsHardToReadMyItems();
Obecjt o = hard.get( "key1" ); // 第一次读取,会花费较长时间
o = hard.get( "key1" ); // 第二次就几乎不需要时间了
o = hard.get( "key2" ); // 我们假设应用还需要其它对象
o = hard.get( "key3" );
o = hard.get( "key1" ); // 由于后面两次的读取成功,key1缓存被废弃了,再次读取时就要重新读了。
2.11.7 区域化格式工具
这个类提供了一些有用的方法,按区域格式化不同的信息,其中主要是日期和时间。
用于格式化的格式和常量使用以下关键字取自ResourceManager:
关键字 说明
format.date 日期格式
format.time 时间格式
format.month.i 月份名称, i的值从1至12, 1表示一月份,12表示十二月份
format.weekday.i 星期名称, i的值与Calendar.MONTH类似, 例如1表示星期天, 2表示星期一, 而7表示星期六
格式的形式类似于JavaSE实现的SimpleDateFormat类。
表达式 意义
d 每月号数(1-31), 有一位数字
dd 每月号数(1-31), 有两位数字(不足两位前面补0)
ddd 星期名称的前三个字母
dddd 星期名称
M 月份(1-12), 有一位数字
MM 月份(1-12), 有两位数字(不足两位前面补0)
MMM 月份名称前三个字母
MMMM 月份名称
yy 年份, 后两位数字(无世纪)
yyyy 年份, 四位数字(有世纪)
h 小时, 0-24, 一位数字
hh 小时, 0-24, 两垃数字(不足两位前面补0)
m 分钟, 0-59, 一位数字
mm 分钟, 0-59, 两垃数字(不足两位前面补0)
s 秒, 0-59, 一位数字
ss 秒, 0-59, 两垃数字(不足两位前面补0)
其他的字母将被全部解释为文字。单引号引起的字符串也被解释为文字。
2.11.8 工具
工具类为本库或其它库中的类提供了一些有用的方法。
2.11.8.1 安全内存分配secureAlloc
将首先尝试分配一块字节数组,拦截可能首次引发的OutOfMemoryError,呼叫垃圾收集器收集无用内在后再次尝试内在分配。
2.11.8.2 数组式矢量arrayAsVector
将一个数组对象转换为矢量。
2.11.8.3 对象相等性比较objectEquals
检查两个对象的相等性,检查null值和对象类。
2.11.8.4 重复
创建一个给定重复字母和长度的字符串。
2.11.8.5 幂
数学上计算给定数的幂
2.11.8.6 取词getWords
将一个字符串分裂成一个单词列表。这是一个可以使用不同的方法将一份文本分裂单词组的多态方法。
2.11.8.7 分裂行splitInLines
该方法通过使用给定的单词、象素长度、和字体将一个字符串分成不同的行。可以指定两种字体,首行为一个字符,其他为一个字体。
如果自动换行被禁止,只有换行字符才会导致跳至下一行,超过换行符后的字符将被丢掉,如果允许自动换行,则将会以单词为界将该行分裂成多行。
3. 许可
该openbasemovil核心库是免费的,基于GPL 2许可开放源代码。
这意味着你可以基于同一条款免费使用它:您的软件必须遵守GPL第2版或更新版本的授权许可。
如果您想要创建商业性的闭源应用,或者您想为此提供支持,请访问www.basemovil.com。
Elondra也提供和支持商业许可,并提供更多的库;我们有一个ISV计划:让你可以充分利用我们所有的库,而不限于openbasemovil核心库(数据库和同步,增强的GUI,通讯,权限管理等等)。您的应用可放置在我们的服务器上并通过它们分发出去,您可以每月从你的客户中得到报酬,我们会中其中得到一个小份额收入。
请参考 http://www.basemovil.com/en/opensource/licensing以得到更详细的许可说明。
3.1 保证
如果Elondra不再继续开发这个库,他们将以Apache 2.0相似的许可发布,允许商业性的使用。
- 09:31
- 浏览 (298)
- 评论 (2)
- 分类: OpenBaseMovil 资料
- 发布在 j2me圈子 圈子
- 相关推荐
发表评论
- 浏览: 13768 次
- 性别:

- 来自: 广州

- 详细资料
搜索本博客
我的相册
jaccount1.0.7
共 5 张
共 5 张
最近加入圈子
链接
最新评论
-
Java 初学者应对以下代码 ...
~呵呵,测试了下你的留言版,不太行哦!~~~
-- by ggweixudong -
Java 初学者应对以下代码 ...
[list=1] [*][list=1] [*][*][list=1] [*] ...
-- by ggweixudong -
能否考虑使用asp实现服务 ...
那就要研究一下asp了,不知道又要花我多长时间呢?干吧,管它呢!
-- by iwinyeah -
能否考虑使用asp实现服务 ...
当然是可以的。而且这些东西,用http协议搞下就OK了。很简单的。
-- by wuhua -
试翻译Openbasemovil-core ...
很不错哦,值得期待。
-- by LinuxFans






评论排行榜