选择显示字体大小

探索j2me:使用记录管理系统

欢迎回到我的j2me系列开发文章。如果你已经从头开始学习这一系列文章,你就会想起上次我们为了可以实现同时编辑现有条目和新增条目的功能而修改了expensesapp应用程序的midlet组件。expenseapp不能在运行过程中存储新增的开销条目,这使得它的作用受到限制。
<--start banner ad--><--ba--><-- language=javascript1.1 src="http://ad.cn.doubleclick.net/adj/messagingplus.z.net.com.cn/developer/code;sz=1x1;ord=138381999?">

在本文中,我们将通过midp的记录管理系统(rms)来为expensesapp midlet组件创建一个记录存储器来解决上述问题。我们将会把expensesapp增强到记录库的程度,这将使得该应用程序——最终在理论上——是有用的。

记录存了些什么?

midp规范要求运行平台提供某种稳固的存储手段(通过非挥发性的存储器,即掉电后存储的信息不会丢失的存储器)。rms(记录管理系统)管理记录库,记录库即为二进制平面文件(flat file,由不包括重复组的一组同类型记录构成的文件)。记录库中的每一段数据都涉及到某一个记录,它还拥有一个由数字组成的记录id号,id在整个记录库中是互不重复的。每一个记录库的名字在创建它的midlet组件中也是互不相同的,midlet只可以访问它自己或同一组件中其它midlet所创建的记录库。当从设备(device)中删除midlet组件时,所有与midlet组件相关的记录库也全部被删除。

javax.microedition.rms软件包包含了recordstore类,recordstore类提供了访问记录库中的数据的初步方法。该软件包还包含了对记录库中的记录进行排序、搜索的其它类。在本文中,为了简明起见,我将集中介绍recordstore类,其它的类将在以后介绍。

recordstore类的运行

recordstore类的运行过程很简单明了。你可以用静态recordstore.openrecordstore方法打开一个已有的记录库,这会为这个指定名字的记录库返回一个recordstore实例。如果你指定的记录库的名字不存在,该方法也可以创建一个以改名字命名的新的记录库(参见createifnecessary参数)。使用getrecord方法你就可以通过记录id来得到id对应的记录。你还可以用addrecordsetrecord方法分别实现添加记录和更新记录的功能。当你完成了对记录库的操作,别忘了用closerecordstore来关闭这个记录库。


关于记录id的一个注释:
在sun公司的标准实现(sun’s reference implementation)中,给定记录的id号与它的插入次序是相同的。记录库中第一个插入的记录以1为它的id号,第二个插入的记录以2为id号,以此类推。尽管这听起来似乎很方便,但是实际上并不总是如此。midp规范只要求每个记录都有一个id号——id号是如何创建的问题则留给平台的实现者。


recordstore类的绝大多数方法都可以抛出一个或者多个recordstoreexception类型的例外。例外的子类和它们对应的意义如下所示:

最后,由于被处理的对象是二进制数据,记录库访问方法(getrecord、addrecordsetrecord)均把记录数据做为字节数组处理。你会发现——除非你有些喜欢被虐待——java.io软件包的流处理类,如bytearrayinputstreambytearrayoutputstreamdatainputstream、和dataoutputstream,使用起来并不可靠。

深入代码

你可以从这儿下载最新版本的expensesapp应用程序的代码。在写本文时,我起初只想修改expenseinfo类,但是recordstore类是由一种古怪(quirky)的方法实现的,这使得这么做会难以置信得复杂。(在别的地方需要好几个try嵌套语句)。结果,我对expensesdetailform类也做了修改,从而简化了整个过程。

事实上,绝大多数rms(记录管理系统)都有类似的怪癖(quirk),把这些怪癖弄到一块会阻碍你的开发进度。下面是一些我曾遇到的问题:不同的类中的功能类似的方法应该有同样或者近似的名字,可是在rms中不是这样;一些方法的名字“名不副实”,会误导你错误认识该方法的功能;还有一些方法会在编程者无法处理的情况下抛出例外。你会发现,如果你经常使用j2me类,拥有一份midp的java文档,或者至少一个有方法提示(method prompting)功能的编辑器是特别值得的。

看看代码清单a,你会发现静态方法expenseinfo.loadexpenses为了从recordstore对象中读取数据而被修改了。当打开或者创建一个记录库后,我会遍历库中所有的记录,把每个记录中的数据提取到一个字节数组中,然后为每一个记录创建一个新的expenseitem实例,并用一个vector返回整套条目。expenseinfo.loadexpenses现在抛出recordstoreexception例外,closerecordstore本身也会抛出例外,因此改变(代码)是不可避免的了,这样,expenses类的构造函数也需要加上一个try语句。

我还用rms的api来更新了expenseinfo.saveexpenseinfo.delete方法。你可以在代码清单b中找到它们。这两个方法通过检查非零记录id(私有expenseid变量)来检测记录是否存在于当前实例中。如果通过方法save来保存一个新的开销记录,就会调用addrecord方法来把该记录添加到记录库中。如果记录已经存在,save方法就调用setrecord方法来更新对应的记录。delete方法工作过程与之类似,如果它的实例没有记录id号就什么也不做(因为它还没有被保存),如果记录id号(expenseid)非零,则调用deleterecord方法来删除对应记录。

还有进一步的工作需要完成

我们已经让expensesapp应用程序前进了一大步,但是尚未全部完成。现在它还存在下列问题:

你能发现这些bug吗?

请你考虑这个练习。首先,去掉expense类的构造函数中的注释符,这样就恢复了先前被注释掉的删除函数。然后运行expensesapp应用程序,并添加若干个新的开销项目。接着,删除你刚才输入的第二个开销项目,并关闭expensesapp。当你再次进入expensesapp就会捕获到一个例外情况。想想这是为什么。

在下一篇探索j2me文章中,我将向你展示如何用recordenumeration类来解决上述两个问题。祝你好运。


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons