`
fanjava
  • 浏览: 235897 次
  • 来自: ...
文章分类
社区版块
存档分类
最新评论

RMS从入门到精通之一

阅读更多

Record Management System是J2ME的一个重要的子系统,目的是实现应用程序本地数据的持久性存储。目前支持文件系统的移动信息设备还有限,因此Record Management System是J2ME开发人员实现本地数据存储的首选途径。本文的目的就是全面的介绍Record Management System的知识。

顾名思义Record Management System是管理数据的系统,Record是系统中最重要的实体。在移动设备存储空间存储的并不是字段,而是字节数组。Mobile Infomation Device Profile(MIDP)规范中并没有规定什么样的数据才能存储为记录,事实上记录是任何可以被字节数组表示的数据,例如图片、文本等。Record Management System的职责是存储和唯一标识记录,而表示数据的任务是由应用程序来完成的,因此J2ME的开发人员往往要花费更多的精力来处理存储空间中的数据。这样做的目的是简化MIDP的实现,使得J2ME的子系统尽量的小巧、灵活。毕竟移动信息设备的存储空间和处理器的能力都有限。

Record Store是一系列记录的有序集合,记录是不能单独存在的,必须属于Record Store。Record Store保证记录的读写操作都是原子的,数据不会被破坏。在API中Record Store是由javax.microedition.rms.RecordStore实现的,关于RecordStore的具体操作在接下来的文章中会有详细的介绍。

MIDP规范中说明移动信息设备要提供至少8K的非易失性存储空间给应用程序来实现数据的持久性存储。但是不同的设备提供的空间并不相同。如果MIDlet suite使用了Record Management System,那么它必须在MANIFEST文件和JAD文件中通过设置MIDlet-Data-Size来说明它所需要的最小的数据存储空间,单位是字节,例如MIDlet-Data-Size:8192。如果你的值超过了移动设备规定的最大值那么你的应用程序将不能正确安装。这个值并不是移动设备真正提供给应用程序的最大Record Management System的存储空间,往往要大一些,因此开发人员应该避免把应用程序需要的最小存储空间设置的过大,必要的时候应该参考相关设备的说明手册。在非易失性存储空间内读写数据往往速度会比较慢,因此针对频繁访问的数据最好提供缓存的机制来提供性能。Record Management System的读写操作是线程安全的,但是由于Record Store是被整个MIDlet suite共享的,所以如果不同MIDlet上运行的线程操作Record Store的时候,我们应该进行必要的线程同步,避免数据被破坏。

MIDP1.0和MIDP2.0中关于Record Management System的实现有些不同,在同一个MIDlet suite里面的MIDlets可以相互访问彼此的Record Store。但是在MIDP1.0的实现中,并没有提供在不同MIDlet suite之间共享Record Store的机制。在MIDP2.0中提供的了新的API来解决不同MIDlet suite之间共享Record Store的问题,在创建Record Store的时候通过授权模式和读写控制参数来进行共享机制的管理,我将在下篇文章中进行详细的介绍。

加强对Record Management System的理解的最好的办法就是进行实际的开发,在进行开发中我发现并不是所有移动设备的MIDP实现都准确无误。当我用getSizeAvaliable()方法查询Nokia6108的可用Record Store空间的时候得到的数值是超过1M字节,但是当我写入40K的数据的时候就出现了RecordStoreFullException异常,因此我编写了一个自动测试手机Record Store最大存储空间的软件。原理是每隔一定时间例如100-500毫秒向Record Store内写入1K字节的数据,当抛出存储空间已满的异常的时候就可以得到最大值了,精确单位为K字节。下面是程序的源代码和JAD文件的内容,开发平台为Eclipse3.0RC2+EclipseME0.4.1+Wtk2.1+J2SDK1.4.2._03,在真机Nokia 6108上测试通过并显示最大值为31K。(请不要在模拟器上进行测试,那样结果没有意义)

总结:本文只是带领读者对Record Management System进行了大概的了解,虽然在文章最后提供了一个应用程序。但是并没有深入分析如何使用Record Management System。在接下来的文章中我们会深入分析javax.microedition.rms包中的类,重点是如何使用RecordStore类。

import javax.microedition.lcdui.Alert;
import javax.microedition.lcdui.AlertType;
import javax.microedition.lcdui.Display;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.rms.RecordStoreException;


public class RMSAnalyzer extends MIDlet
{

private Display display;
private CounterCanvas counterCanvas;
private Alert alert;


protected void startApp() throws MIDletStateChangeException
{

display = Display.getDisplay(RMSAnalyzer.this);
alert = new Alert("错误提示");
try
{
String interval = this.getAppProperty("INTER");
int t = Integer.parseInt(interval);
counterCanvas = new CounterCanvas(t, 1, this);
}
catch (RecordStoreException e)
{
this.showAlertError(e.getMessage());
}
display.setCurrent(counterCanvas);

}

public Display getDisplay()
{
return display;
}


protected void pauseApp()
{

}


protected void destroyApp(boolean arg0) throws MIDletStateChangeException
{

}

public void showAlertError(String message)
{
alert.setString(message);
alert.setType(AlertType.ERROR);
alert.setTimeout(3000);
display.setCurrent(alert);

}

}

import java.util.Timer;
import java.util.TimerTask;

import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.midlet.MIDletStateChangeException;
import javax.microedition.rms.*;


public class CounterCanvas extends Canvas implements CommandListener
{

private RMSModel model;
private RMSAnalyzer RMSanalyzer;
private int interTime;
private int counter;
private boolean go = true;
public static Command backCommand = new Command("退出", Command.EXIT, 3);
public static final int INC = 1;
public final Timer timer = new Timer();

public CounterCanvas(int interTime, int base, RMSAnalyzer rmsa)
throws RecordStoreException
{
this.interTime = interTime;
this.counter = base;
this.RMSanalyzer = rmsa;
model = new RMSModel(base, RMSanalyzer);
this.addCommand(backCommand);
this.setCommandListener(this);

TimerTask timerTask = new TimerTask()
{
public void run()
{

try
{
model.writeRecord(INC);
counter++;
} catch (RecordStoreFullException e)
{
go = false;
model.deleteRMS();
timer.cancel();
} catch (RecordStoreException e)
{
model.deleteRMS();
RMSanalyzer.showAlertError(e.getMessage());
timer.cancel();
}
repaint();

}
};

timer.schedule(timerTask, 1000, interTime);

}


public void setCounter(int counter)
{
this.counter = counter;
}


public void setInterTime(int interTime)
{
this.interTime = interTime;
}


protected void paint(Graphics arg0)
{

int SCREEN_WIDTH = this.getWidth();
int SCREEN_HEIGHT = this.getHeight();
arg0.drawRect(SCREEN_WIDTH / 10, SCREEN_HEIGHT / 2,
SCREEN_WIDTH * 4 / 5, 10);
if(RMSanalyzer.getDisplay().isColor())
{
arg0.setColor(128, 128, 255);
}
arg0.fillRect(SCREEN_WIDTH / 10, SCREEN_HEIGHT / 2, counter, 10);
if (!go)
arg0.drawString("最大值:" + counter+"K字节", 0, 0, Graphics.TOP
| Graphics.LEFT);

}

public void commandAction(Command arg0, Displayable arg1)
{

if (arg0 == backCommand)
{
try
{
model.deleteRMS();
RMSanalyzer.destroyApp(false);
RMSanalyzer.notifyDestroyed();
} catch (MIDletStateChangeException e)
{

}
}

}

}


import javax.microedition.rms.*;

public class RMSModel
{
public static final int K = 1024;
private RecordStore rs;
private int baseCount;
private RMSAnalyzer RMSanalyzer;
public static final String name = "test";

public RMSModel(int baseCount, RMSAnalyzer rmsa)
throws RecordStoreException
{
this.baseCount = baseCount;
this.RMSanalyzer = rmsa;
if (rs == null)
{
rs = RecordStore.openRecordStore(name, true);
writeRecord(baseCount);
}
}

public void writeRecord(int count) throws RecordStoreException
{
byte[] data = new byte[count * K];
for (int i = 0; i < count; i++)
{
data[i] = 1;
}
rs.addRecord(data, 0, count * K);
}

public void deleteRMS()
{
try
{
rs.closeRecordStore();
RecordStore.deleteRecordStore(name);
} catch (RecordStoreException e)
{
RMSanalyzer.showAlertError(e.getMessage());
}
}
}

RMSAnalyzer.jad

MIDlet-Jar-Size: 5293
MIDlet-1: RMSAnalyzer,,RMSAnalyzer
MIDlet-Jar-URL: RMSAnalyzer.jar
MicroEdition-Configuration: CLDC-1.0
MIDlet-Version: 1.0.0
MIDlet-Name: RMSAnalyzer
MIDlet-Data-Size: 8192
MIDlet-Vendor: Midlet Suite Vendor
MicroEdition-Profile: MIDP-1.0
INTER: 100

分享到:
评论

相关推荐

    J2ME从入门到精通

    **J2ME从入门到精通** Java Micro Edition(J2ME)是Java平台的一个子集,主要用于嵌入式系统和移动设备,如早期的智能手机、电视盒和家用电器。本教程将带你逐步深入J2ME的世界,理解其基本概念、开发环境搭建、...

    j2me程序开发实用案例从入门到精通

    《J2ME程序开发实用案例从入门到精通》是一本专为Java初学者和开发者设计的教程,旨在帮助读者深入理解和掌握J2ME(Java 2 Micro Edition)平台的编程技术。J2ME是Java技术在移动设备和嵌入式系统上的应用版本,广泛...

    J2ME实用教程:从入门到精通的所有ppt

    在《J2ME实用教程:从入门到精通的所有ppt》中,你可以期待学习以下关键知识点: 1. **J2ME架构**:了解CLDC(Connected Limited Device Configuration)和MIDP(Mobile Information Device Profile)是如何构成...

    ZEMAX光学设计软件 学习手册

    1. **广泛的适用范围**:ZEMAX支持多种类型的光学系统设计,从简单的单透镜到复杂的多元件系统均可处理。 2. **强大的功能集**:软件提供了丰富的工具和功能,如光线追踪、优化算法、数据分析等,帮助用户高效地完成...

    精通J2ME无线编程

    《精通J2ME无线编程》是一本专注于Java Micro Edition(J2ME)技术的书籍,主要针对想要在无线设备上进行开发的程序员。J2ME是Java平台的一个子集,设计用于资源有限的嵌入式设备,如移动电话、PDA和家用电器等。这...

    J2ME手机开发入门知识必读

    J2ME,全称Java 2 Micro Edition,是Java平台的一个子集,专门用于嵌入式设备和移动设备的开发,尤其是手机应用。本教程针对的是J2ME手机开发的入门学习者,旨在帮助初学者掌握基本的手机程序开发流程。 一、J2ME...

    J2ME程序开发新手入门九大要点

    3. J2ME游戏移植人员:将游戏从一个平台移植到另一个平台,要求了解不同平台的技术规格和差异。 五、J2ME程序设计原则 1. 面向对象编程:即便可能导致文件大小增加,也应优先选择面向对象编程,以便于代码的维护和...

    ArcGIS基本操作教程大全

    通过上述知识点的介绍和操作演示,该教程旨在为用户提供一套全面、实用的ArcGIS学习资源,帮助用户从入门到精通,全面掌握ArcGIS软件的使用技巧和各种功能。需要强调的是,教程的每个部分都有可能结合具体的操作界面...

    j2me撞砖游戏

    《J2ME撞砖游戏详解:入门到精通》 J2ME(Java 2 Micro Edition)是Java平台的一个重要分支,主要用于开发移动设备、嵌入式系统等小型应用,其中包括了我们今天要讨论的“撞砖游戏”。这款游戏简单易懂,非常适合...

    PDF-BeginningJavaMEPlatformPDFBooks-英文版.rar

    《 Beginning Java ME Platform》是一本专注于Java Micro Edition(Java ME)平台开发的入门级书籍,适合初学者和有一定编程基础的开发者。Java ME是Oracle公司为小型设备和嵌入式系统设计的一套Java应用程序框架,...

    J2ME 手机程序开发

    ### 第一章:J2ME入门 1. **J2ME体系结构**:J2ME由几个关键组件构成,包括Connected Limited Device Configuration (CLDC)和Connected Device Configuration (CDC)。CLDC适用于内存和处理能力有限的设备,如基本...

    J2ME程序开发全方位基础讲解汇总

    J2ME中的数据存储通常通过Record Management System (RMS) 实现,这是一种简单的键值对存储方式。开发者可以使用RecordStore类来读写数据。 8. **网络编程** MIDP提供了HttpConnection类进行HTTP通信,可以实现...

    J2me开发须知

    3. **J2ME游戏移植人员**:将游戏从一个平台移植到另一个平台,需要了解平台差异和技术参数。 **五、J2ME程序设计原则** 1. **面向对象编程**:即使牺牲一些体积,也要保持代码的可维护性和可扩展性。 2. **MVC...

Global site tag (gtag.js) - Google Analytics