虽然配置为一组通用设备提供了最小的 Java平台,但是应用程序开发者感兴趣的是为一个个别的设备生产应用程序,当他们只是使用配置的话,他们编写的应用程序就会有一些欠缺。 配置必须满足所有的设备的最小的要求, 用户界面、输入机制和数据持久性有高度地设备具体性,每一种设备都有自己的用户界面、输入机制和数据存储方法,这些往往不在配置所满足的最小要求的范围之内。
简表为相同消费电子设备的不同的生产商提供了标准化的 Java类库, 事实上,虽然配置规范的开发由 Sun领导,但是许多简表规范仍将继续由特殊设备的供应商领导。 比如说, Motorola领导了行动电话和呼叫器简表规范的开发,又如 Palm 领导 PDA简表的开发。
现在,五个已知简表已经有了规范, 记住,每个简表的责任都是为了完善配置的不足,下表列出了这五个简表:
简 表 完善配置 Mobile information devices profile (MIDP) 移动电话和呼叫器 CLDC Personal digital assistant profile Palm和Handspring的PDA 设备 CLDC Foundation profile 用于所有不需要GUI的CDC设备的标准简表 CDC Personal profile 替代PersonalJava的Foundation完善的简表 CDC RMI profile 提供RMI的Foundation完善的简表 CDC
现在我想谈一谈另一个Java类库集,它现在差不多可以被认为是另一个简表了。当Sun为Palm开发第一个KVM时,他们需要一组类来 开发Palm的演示程序。这套类库被封装进 com.sun.kjava程序包, 在 CLDC早期的开发中,这些类被广泛的使用来测试和演示 J2ME.因为 kjava是唯一的允许应用程序开发者使用 J2ME和 KVM开发应用程序的类,所以它就被广泛使用了。甚至到了今天,一个用于 PDA或更特殊一点的 Palm的简表多已经在开发中,许多开发者仍然希望使用 kjava类来开发 PDA应用程序。尽管 kjava类不被支持,并且仅仅用于设计测试程序或演示程序,并且它们将被一个即将到来的简表所替代,但是开发者们仍然热衷于使用它来开发。
MIDP
Mobile Information Device Profile(移动信息设备简表 ,简称 MIDP ),第一个实现的简表,补充了 CLDC并且提供应用程序语义和控件、用户界面、持久存储器、网络和用于移动电话的计时器、双通道呼叫器和其他无线电设备。 因为 MIDP和 CLDC两者都有引用实现,我们可以使用一个例程来研究一下这个简表。
下面的例子是一个允许用户输入代表想知道的基金报价的代号的例子。应用程序然后通过 HTTP接到一个金融网站,获得基金报价,把价格储存在一个数据库,然后把价格返回给用户。
// 到如需要的J2ME类
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.rms.*;
// 扩展MIDlet类来构建我们的自定义MIDlet
public class FundTracker extends MIDlet implements
CommandListener {
file://显示管理者变量
private Display display = null;
file://MIDlet的表单变量
private RequestForm reqForm = null;
file://MIDlet构建器
public FundTracker () {
display = Display.getDisplay(this);
reqForm = new RequestForm("Fund Tracker");
reqForm.initForm();
reqForm.setCommandListener(this);
}
file://开始 MIDlet 应用程序
protected void startApp() {
display.setCurrent(reqForm);
}
file://暂停 Midlet
protected void pauseApp() {
}
file://销毁Midlet
protected void destroyApp(boolean unconditional) {
}
file://通过监听者响应命令
public void commandAction(Command c, Displayable s) {
if (c == reqForm.getExitCommand()) {
destroyApp(false);
notifyDestroyed();
return;
}
if ((c == reqForm.getGetCommand()) &&
(reqForm.getSymField().getString().length() > 0)) {
getAndDisplayQuote();
} else
{
reqForm.getMsgString().setText("Symbol required");
}
}
file://储存由#分开的成对的基金字符串和报价字符串
private void storeQuote (String fund, String newQuote) {
file://数据库变量
RecordStore quoteDB = null;
try {
quoteDB = RecordStore.openRecordStore(
"FundQuotes", true);
byte[] data = (fund + "#" + newQuote).getBytes();
int size = data.length;
quoteDB.addRecord(data, 0, size);
quoteDB.closeRecordStore();
}
catch (Exception recordException) {
System.out.println("Unable to store quote and/or
use Fund Quote database.");
}
}
file://通过QuoteService类取回提交的代号表示的基金报价
private void getAndDisplayQuote(){
String fundSymbol = reqForm.getSymField().getString();
if (fundSymbol.length() > 0) {
String theQuote = QuoteService.getQuote(fundSymbol);
if (theQuote != null) {
storeQuote(fundSymbol, theQuote);
reqForm.getMsgString().setText(theQuote);
}
else
reqForm.getMsgString().setText("No quote" +
'\n' + "Check Symbol");
}
}
}
MIDP应用程序称为 MIDlet, 为了创建一个 MIDlet,你必须写一个扩展基本 MIDlet类的类 (就像我们在上面代码段中列出的那样)。 这有点类似常见的 applet或 servlet. MIDlets独有的东西是把多个 MIDlet组成一个 MIDlet套件的能力。 这就允许 MIDlet在一个单独的 JVM环境中共享资源,比如一个数据库等等。 事实上,我们上面给出的例子还包括一个 MIDlet ( RetrieveQuote,见上段程序),用于取回所报价格。 当MIDlet被请求时, MIDlet通过构造程序实例化,然后调用实例的 startApp()方法。
在 FundTracker例子中, MIDlet的用户界面或显示是由 Display类的一个实例管理的。 对于每个 MIDlet,只有一个显示管理器实例。 所有可以显示的项目,像屏幕或画布(canvas),通过这个管理器都能够成为可见的。因为行动电话和呼叫器能力的多样化,又因为用于这些设备的应用程序类型的差异, MIDP规范提供了两种类型的用户界面。一个可移植性稍差、明确设备、低水平的应用程序接口,允许图形元素精确的控制和放置。 这个接口类型是用于应用程序特性比较典型的设备特别设计的,比如电子游戏。 一个可移植性稍好的、抽象的、高级的 GUI应用程序接口,提供来用于商业应用程序。
我们的例程使用的是高级的应用程序接口和典型的用户界面组件 (文本框,列表等等 ),是这类界面通用的。比如说,实际的表单和所有的小组件在一个单独的文件中都已定义。 就像在代码段一中列出的那样,当 MIDlet创建时,一个表单的实例与 MIDlet关联。 在调用 MIDlet startApp()方法的时候,通过 Display对象显示表单。 使用一个用于表单的类,允许我们在我们简单的报价检索应用程序中重新使用这个表单 ( RetrieveQuote )。为了清晰性和风格,我们通过一个单独的类来定义报价服务。 为了演示一般连接器结构的能力,我们的报价服务类通过一个 Connector实例取回报价。