| <--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.openrecordstore方法打开一个已有的记录库,这会为这个指定名字的记录库返回一个recordstore实例。如果你指定的记录库的名字不存在,该方法也可以创建一个以改名字命名的新的记录库(参见createifnecessary参数)。使用getrecord方法你就可以通过记录id来得到id对应的记录。你还可以用addrecord和setrecord方法分别实现添加记录和更新记录的功能。当你完成了对记录库的操作,别忘了用closerecordstore来关闭这个记录库。
recordstore类的绝大多数方法都可以抛出一个或者多个recordstoreexception类型的例外。例外的子类和它们对应的意义如下所示:
最后,由于被处理的对象是二进制数据,记录库访问方法(getrecord、addrecord和setrecord)均把记录数据做为字节数组处理。你会发现——除非你有些喜欢被虐待——java.io软件包的流处理类,如bytearrayinputstream、bytearrayoutputstream、 datainputstream、和dataoutputstream,使用起来并不可靠。
你可以从这儿下载最新版本的expensesapp应用程序的代码。在写本文时,我起初只想修改expenseinfo类,但是recordstore类是由一种古怪(quirky)的方法实现的,这使得这么做会难以置信得复杂。(在别的地方需要好几个try嵌套语句)。结果,我对expenses和detailform类也做了修改,从而简化了整个过程。
事实上,绝大多数rms(记录管理系统)都有类似的怪癖(quirk),把这些怪癖弄到一块会阻碍你的开发进度。下面是一些我曾遇到的问题:不同的类中的功能类似的方法应该有同样或者近似的名字,可是在rms中不是这样;一些方法的名字“名不副实”,会误导你错误认识该方法的功能;还有一些方法会在编程者无法处理的情况下抛出例外。你会发现,如果你经常使用j2me类,拥有一份midp的java文档,或者至少一个有方法提示(method prompting)功能的编辑器是特别值得的。
看看代码清单a,你会发现静态方法expenseinfo.loadexpenses为了从recordstore对象中读取数据而被修改了。当打开或者创建一个记录库后,我会遍历库中所有的记录,把每个记录中的数据提取到一个字节数组中,然后为每一个记录创建一个新的expenseitem实例,并用一个vector返回整套条目。expenseinfo.loadexpenses现在抛出recordstoreexception例外,closerecordstore本身也会抛出例外,因此改变(代码)是不可避免的了,这样,expenses类的构造函数也需要加上一个try语句。
我还用rms的api来更新了expenseinfo.save和 expenseinfo.delete方法。你可以在代码清单b中找到它们。这两个方法通过检查非零记录id(私有expenseid变量)来检测记录是否存在于当前实例中。如果通过方法save来保存一个新的开销记录,就会调用addrecord方法来把该记录添加到记录库中。如果记录已经存在,save方法就调用setrecord方法来更新对应的记录。delete方法工作过程与之类似,如果它的实例没有记录id号就什么也不做(因为它还没有被保存),如果记录id号(expenseid)非零,则调用deleterecord方法来删除对应记录。
我们已经让expensesapp应用程序前进了一大步,但是尚未全部完成。现在它还存在下列问题:
请你考虑这个练习。首先,去掉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 安全 模式 框架 测试 开源 游戏
Windows XP Windows 2000 Windows 2003 Windows Me Windows 9.x Linux UNIX 注册表 操作系统 服务器 应用服务器