[Java中级教程]第六讲 数据的保存和读取-----转

■ 引言

  在上讲中,我们认识到汲取音乐播放的专长,能够制作成拥有BGM和音效、表现力丰富的应用程序。在本讲中,我们主要就应用程序本身内部保持的数据保存、读取进行详细阐述。

■ 数据的保存读取

  RMS:

  要在应用程序中保存用户设定和高分等相关信息,所以必须在手机终端上的记忆中保存数据。MIDP上定义了称之为RMS(Record Management System)的数据库系统。RMS中有称为“Record store”的列表,其中存在名为Record 的entry。Record按照字节排列,用id可以识别。利用下面的类、接口可以操作Record Store和Record。

                     类、接口名                                     作用
 RecordStore表示Record Store的类
 RecordEnumeration列举Record的接口
 RecordComparator定义Record comparator的接口
 RecordFilter定义Record过滤的接口
 RecordListener监视Record Store变更的接口

表 1

  RecordStore

  表示Record Store的是Record Store类。Record Store是用RecordStore 中的static方法的open Record Store制作的。

  RecordStore.openRecordStore("RecordStoreName", true);

  第2个自变量转化成“true”后,名为“Record Store Name”的Record Store存在的情况下,能够打开保存的Record Store。但是,名为“Record Store Name”的Record Store不存在的情况下,则会制作新的Record Store,并打开所制作的Record Store 。

  第2个自变量转化成“false”后,名为“Record Store Name”的Record Store存在的情况下,能够打开保存的Record Store。但,不存在的情况下,则放弃Record Store Not Found Exception。
操作Record Store时,应该在操作前打开Record Store,并在操作完后关闭Record Store。利用刚刚介绍的Record Store的static方法——open Record Store打开Record Store。利用Record Store的引证方法的close Record Store按照下面的叙述可以关闭Record Store。在这儿将关闭的Record Store 例子表示为rs。

  rs.closeRecordStore();

  以下是表示针对 Record Store 的连贯操作。(ex. 1)

RecordStore rs = null;
try{
    // 打开Record Store
    rs = RecordStore.openRecordStore("RecordStoreName",true);

    记述针对Record Store的操作
    ?
    ?

}catch(Exception e){
}finally{
    if(rs != null){
        try{
            // 关闭Record Store
            rs.closeRecordStore();
        }catch(Exception e){
        }
    }
}

ex. 1

 

  按照下面所述的Record Store的static方法清除Record Store。
  RecordStore.deleteRecordStore("RecordStoreName");

  RMS的限制

  RMS是非常单纯的数据库系统,所以只需准备最小限度的操作。因此,一般数据库系统所具有的处理控制和系统故障的恢复功能,在RMS上是不能被支持的。

  Record操作

    增加Record

    利用以下Record Store类的方法增加Record 。

    int addRecord(byte[] data,int offset, int numBytes)

    在data中指定希望保存的数据字节排列、在offset中指定数据显示排列中的数据开始位置、在numBytes中指定保存数据的字节数。能在numBytes中指定0。此时,null被收藏在Record中。另外,增加数据的Record的id作为返还值返还。

    清除Record

    利用以下方法清除Record 。

    void deleteRecord(int recordId)

    指定用recordId清除Record中的id。对应的Record不存在的情况下,放弃例外。而且,清除后的RecordrecordId也不能再次利用。

    更改Record

    利用以下方法更改Record 。

    void setRecord(int recordId, byte[] newData, int offSet, int numBytes)

    指定recordId中更改的Record,并在newData中指定新收藏的数据字节排列。对应的Record不存在的情况下,放弃例外。

    获取Record

    利用下面的方法获取Record。

    int getRecord(int recordId, byte[] buffer, int offset)

    byte[] getRecord(int recordId)

    上述方法是指,从offset的位置上复制recordId方法指定的Record内容到buffer字节排列。返还值是所复制的数据的字节数。

    下面的方法是指,recordId所指定的Record内容作为返还值返还。

  Record Store的信息

  利用如下方法可以获得Record Store操作和Record 操作之外的Record Store信息。

                  方法                                                功能
 public int getLastModified()用long获取最后的修改时刻。用System.currentTimeMillis()形成能够取得的形式相同的形式。
 public int getNextRecordID()获取下一个recordId。
 public int getNumRecords()获取Record Store中的Record 数。
 public int getVersion()获取Record Store的版本编号。版本编号通常在每次修改完Record Store后都会自动加1。
 public int getSizeAvailable()获取Record Store的容许量。
 public int getSize()获取Record Store的占有字节数。
 public static String[] listRecordStores()全部获取Record Store名。

表 2

 

  RecordEnumeration

  RMS中准备了能够访问Record Store中的全部Record 的RecordEnumeration接口。由于厂商进行具体实际安装,所以开发者就没必要实际安装RecordEnumeration了。RecordEnumeration是具有双向链接的list,在各自的Note中都保存了recordId。

    制作RecordEnumeration

    利用下面的Record Store Instance方法制作RecordEnumeration。

    RecordEnumeration enumerateRecords(RecordFilter filter, RecordComparator comparator, boolean keepUpdated)

    一旦keepUpdated成为true,就会增加Record Store中的Record 的更改量,同时RecordEnumeration也会随着更新。成为False时,只要不呼出RecordEnumeration接口的rebuild()方法,即使在Record Store上增加变更,也不能反映,但可能会得到清除后的recordId。在Filter中将用于过滤Record的RecordFilter接口指定为实际安装的类的接口。此外,在comparator中将用于定义Record顺序号的RecordComparator接口指定为实际安装的类的接口。后面将详细说明。

    访问Record

   应用以下方法访问利用RecordEnumeration的Record。

                                方法                                  作用
 void destroy()取消RecordEnumeration
 boolean hasNextElement()调查是否有下一个Record
 boolean hasPreviousElement()调查是否有前一个Record
 byte[] nextRecord()取得下一个Record
 int nextRecordId()取得下一个Record的ID
 byte[] previousRecord()取得前一个Record
 int previousRecordId()取得前一个Record的ID
 int numRecords()取得Record的数
 void rebuild()再构筑RecordEnumeration
 void reset()将Record的pointer返回到开头

表 3

  如下所示的是利用RecordEnumeration所取得的简单Record。

import javax.microedition.midlet.*;
import javax.microedition.rms.*;

/**
* 表示Record Store的内容
*/
public class RecordStoreTest1 extends MIDlet {

    /**
    * 启动时运行的方法
    */
    protected void startApp() throws MIDletStateChangeException {

        RecordStore rs = null;
        RecordEnumeration re = null;
        try {

            rs = RecordStore.openRecordStore("test",true);//读取Record Store
            re = rs.enumerateRecords(null,null,true);// 列举Record

            // 取得并表示Record
            byte[] data;
            while(re.hasNextElement()){
            data = re.nextRecord();
            System.out.println("record =" + data);
        }

        } catch (Exception e) {
        } finally {
            // 取消Record 的列举
            if (re != null) {
                try {
                        re.destroy();
                } catch (Exception e) {
                }
            }

            // 关闭Record Store
            if (rs != null) {
                try {
                    rs.closeRecordStore();
                }catch(Exception e){
                }
            }
        }

    }

    protected void pauseApp() { }

    protected void destroyApp(boolean arg0) throws MIDletStateChangeException { }

}

ex. 2

  RecordFilter

  用RecordEnumeration取得Record时,指定条件能够过滤Record。实际安装RecordFilter接口,该Instance在RecordEnumeration完成时就成为构造函数的自变量,所以能够过滤。RecordFilter接口中定义了如下方法。

  boolean matches(byte[] candidate)

  此方法中记述了过滤的条件,还记述了若条件适合则返回到true,若不合适则会返回到false。

  以下显示的是实际安装完RecordFilter的TestFilter。此例中过滤了比用构造函数所指定的数值还低的数值。

import javax.microedition.rms.RecordFilter;

/**
* Record过滤
* 过滤被指定的数值以下的数值
*/
public class TestFilter implements RecordFilter {

    private int min;// 数值的下限

    /**
    * 构造函数
    */
    public TestFilter(int min){
        this.min = min;
    }

    /**
    * 过滤
    */
    public boolean matches(byte[] data) {
        if(data[0] > min){
            return true;
        }else{
        return false;
        }
    }
}

ex. 3

  在取得ex. 2的程序的RecordEnumeration画面中,将程序更改为

  re = rs.enumerateRecords(new TestFilter(4),null,true);

  在自变量上指定ex. 3的TestFilter时的运行结果如下所示。(图 1)。


图 1

RecordComparator

  用RecordEnumerator取得Record时,能够进行利用RecordComparator接口所取得的Record的Comparator。RecordComparator中定义了下面方法。

  int compare(byte[] rec1, byte[] rec2)

  返还值中返还了以下3个定数。

 RecordComparator.PRECEDES在Comparator上Record rec1到达Record rec2的前一位置时
 RecordComparator.FOLLOWS在Comparator上Record rec1到达Record rec2的后一位置时
 RecordComparator.EQUIVALENT在Comparator上Record rec1到达Record rec2的同一位置时

表 4

  以下显示的是实际安装RecordComparator的TestComparator。在此例中,按照数值的大小顺序进行比测Record。(ex. 4)

import javax.microedition.rms.RecordComparator;

/**
* 比较Record并定义Comparator顺序
*/
public class TestComparator implements RecordComparator {

    /**
    * 比较Record
    */
    public int compare(byte[] rec1, byte[] rec2) {

        if(rec1[0] == rec2[0]){
            return RecordComparator.EQUIVALENT;
        }else if(rec1[0] > rec2[0]){
            return RecordComparator.PRECEDES;
        }else {
            return RecordComparator.FOLLOWS;
        }
    }
}

ex. 4

  取得ex. 2程序的RecordEnumeration的画面中,程序变更为

  re = rs.enumerateRecords(new TestFilter(3),new TestComparator,true);

  并自变量中指定ex. 4的TestComparator时的运行结果。该内容如下图所示(图 2)。


图 2

  RecordListener

  利用RecordListener接口,能够监视针对Record Store的变更。例如,同期取得两个Record Store的情况下,单方面的Record Store被更改时,能够实现在单方的Record Store上增加更改等的操作。

  RecordListener中有recordChanged,recordAdded,recordDeleted等3个种类的事件,并分别定义了每个方法。

  void recordAdded(RecordStore recordStore, int recordId)

  void recordChanged(RecordStore recordStore, int recordId)

  void recordDeleted(RecordStore recordStore, int recordId)

  利用Record Store类中所准备的如下方法能够在Record Store 上登记RecordListener。

  void addRecordListener(RecordListener listener)

  void removeRecordListener(RecordListener listener)

  以下是实际安装RecordListener的Instance。此示范程序中,可以监视并复制Record的操作。

import javax.microedition.midlet.*;
import javax.microedition.rms.*;

/**
* 表示Record Store内容
*/
public class RecordStoreTest2 extends MIDlet implements RecordListener{

    /**
    * 启动时所运行的方法
    */
    protected void startApp() throws MIDletStateChangeException {

        RecordStore rs = null;
        RecordEnumeration re = null;
        try {
            rs = RecordStore.openRecordStore("test",true);// 读取Record Store
            RecordFilter filter = new TestFilter(3);
            RecordComparator comparator = new TestComparator();

            // 增加RecordListener
            rs.addRecordListener(this);

            // 将数据加入Record Store
            if(rs.getNumRecords() < 1){
                byte[] data = new byte[1];
                for(int i=0;i < 10;i++){
                    data[0] = (byte)i;
                    rs.addRecord(data,0,data.length);
                }
            }

            // 增加Record
            byte[] data = new byte[1];
            data[0] = (byte)3;
            rs.addRecord(data,0,data.length);

            // 清除Record
            rs.deleteRecord(7);

            // 更改Record
            rs.setRecord(8,data,0,data.length);

            // 取得并表示Record
            re = rs.enumerateRecords(filter,comparator,true);// 列举Record
            while(re.hasNextElement()){
                data = re.nextRecord();
                System.out.println("record =" + data[0]);
            }

        } catch (Exception e) {
        } finally {
            // 取消Record 的列举
            if (re != null) {
                try {
                    re.destroy();
                } catch (Exception e) {
                }
            }

            // 关闭Record Store
            if (rs != null) {
                try {
                    rs.closeRecordStore();
                }catch(Exception e){
                }
            }
        }
    }

    protected void pauseApp() { }

    protected void destroyApp(boolean arg0) throws MIDletStateChangeException { }

    /**
    * 增加Record 时的处理
    */
    public void recordAdded(RecordStore recordStore, int recordId) {
        try{
            System.out.println(recordStore.getRecord(recordId)[0]+"is added.");
        }catch(Exception e){
        }
    }

    /**
    * 更改RecordRecord时的处理
    */
    public void recordChanged(RecordStore recordStore, int recordId) {
        try{
            System.out.println(recordStore.getRecord(recordId)[0]+"is changed");
        }catch(Exception e){
        }

    }

    /**
    * 取消Record时的处理
    */
    public void recordDeleted(RecordStore recordStore, int recordId) {
        try{
            System.out.println(recordStore.getName()+"id:"+recordId+"is deleted.");
        }catch(Exception e){
        }
    }

}

ex. 5

  下图是运行结果。(图3)该图能够确认Record 操作内容是被监视并被表示的。


图3

  开始制作应用程序了。

  手机记事本的说明

  利用MIDP的RMS功能,制作手机简易记事本应用程序。

  就是用户输入记事内容,保存输入的内容、并进行记事的编辑、清除等所谓的简单的记事本应用程序。

  如下是画面结构。

Memo list画面显示Memo list。可以进行Memo的重新制作和显示。显示每个Memo的最后访问日期和时间。
Memo画面表示Memo的内容。可以进行Memo的编辑、清除。

 

  下图是画面迁移图。(图 4)


图 4

  手机记事本的实际安装

    下面是实际安装的顺序
    1. 制作模型
    2. 制作画面的实物模型
    3. 制作RMS的操作

    1. 制作模型

  在本记事本中,要制作成表示一个一个的记事的Memo类。Memo类中有最后访问日期和时间、记事内容等属性。(ex. 6)

import java.io.*;
import java.util.*;


/**
* Memo类
*/
public class Memo {

    private Date date;
    private String content = "";

    /**********************************
    * 构造函数
    **********************************/
    public Memo(){
        date = new Date();
    }

    public Memo(String content, Date date) {
        this.content = content;
        this.date = date;
    }

    /**********************************
    * Getter & Setter
    **********************************/
    /**
    * 取得内容
    */
    public String getContent() {
        return content;
    }

    /**
    * 取得最后访问的日期和时间
    */
    public Date getDate() {
        return date;
    }

    /**
    * 设定内容
    */
    public void setContent(String string) {
        content = string;
        date = new Date();
    }

    /**
    * 设定最后访问的日期和时间
    */
    public void setDate(Date date) {
        this.date = date;
    }
}

ex. 6

    2. 制作画面的实物模型

  接下来制作画面与画面之间的迁移。

  本讲讲述利用高级API制作画面。Memo list用高级API的List表示,Memo画面则利用TextBox。

  而且,还要在各个画面中设定命令。分别设定如下表格所示的命令。

 Memo list画面 ADD重新制作Memo
 SHOW显示Memo
 Memo画面 OK刷新Memo的内容
 DELETE清除Memo

  以下内容是实际安装画面实物模型的具体步骤。对于实物模型,Sample Source命令实际安装所记述的处理后,则应用程序就完成了。

import java.util.Vector;

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;
import javax.microedition.rms.*;

/**
* 手机记事本(画面实物模型版)
*/
public class MobileMemo extends MIDlet implements CommandListener {

    // 画面类
    private Display display;
    private Form inputForm;
    private List list;
    private TextBox memoText;

    // 命令群
    private Command add = new Command("ADD", Command.OK, 1);
    private Command show = new Command("SHOW", Command.OK, 1);
    private Command ok = new Command("OK", Command.OK, 1);
    private Command delete = new Command("DELETE", Command.OK, 1);

    /**
    * 构造函数
    */
    public MobileMemo() {
        display = Display.getDisplay(this);

        // 完成Memo list
        initializeList();

        // 作成记事显示画面
        initializeMemoText();

    }

    /**
    * 进行Memo list的初期化
    */
    private void initilizeList(){
        list = new List("MEMO LIST", List.EXCLUSIVE);
        list.addCommand(show);
        list.addCommand(add);
        list.setCommandListener(this);
    }
    /**
    * 进行记事显示画面的初期化
    */
    private void initilizeMemoText(){
        memoText = new TextBox("MEMO", "", 100, TextField.ANY);
        memoText.addCommand(ok);
        memoText.addCommand(delete);
        memoText.setCommandListener(this);
    }

    /**
    // 开始应用程序
    */
    protected void startApp() throws MIDletStateChangeException {

        // 从Record Store读取信息

        // 转换到Memo list画面
        display.setCurrent(list);
    }

    /**
    // 暂时停止应用程序
    */
    protected void pauseApp() {}

    /**
    // 结束应用程序
    */
    protected void destroyApp(boolean bool) throws     MIDletStateChangeException {}

    /**
    * 命令处理
    */
    public void commandAction(Command c, Displayable d) {

        if (d == list) {
            if (c == add) {
            // 重新制作Memo

            } else if (c == show) {
            // 取得Memo

            }

            // 转换到Memo显示画面
            display.setCurrent(memoText);
        } else if (d == memoText) {
            if (c == ok) {
                // RecordMemo内容

            } else if (c == delete) {
                // 清除Memo内容
            }

            // 转换到Memo list
            display.setCurrent(list);
        }
    }
}

  按照上面表格中的程序所示,则可完成实物模型,并能完成应用程序的大致框架。

    3. 完成RMS的操作

    马上就要完成RMS操作了。

    现在我们只想在 Record store中原样保存Memo内容,所以就要在刚才作成的Memo类中进行精雕细琢。从取得Memo类字节排列方法和字节排列中增加制作Memo类的构造函数。而且,还能用Memo类保存Record ID。(Record store中保存的Record ID则不写入。)

    利用ByteArrayOutputStream类和DataOutputStream类,变换字节排列中的类的内容。Memo类中记述了如下Instance方法。(ex. 7)

/**
* 变换字节排列
*/
public byte[] toBytes(){
    byte[] data = null;
    try{
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        DataOutputStream out = new DataOutputStream(baos);

        out.writeLong(date.getTime());
        out.writeUTF(content);
        data = baos.toByteArray();

        baos.close();
        out.close();

    }catch(Exception e){
    }

    return data;
}

ex. 7

    还是从字节排列中制作作成Memo对象的构造函数吧!利用ByteArrayInputStream类、DataInputStream类,如下记述。(ex. 8)

public Memo(byte[] data){
    ByteArrayInputStream bais = new ByteArrayInputStream(data);
    DataInputStream in = new DataInputStream(bais);
    try{
        date = new Date(in.readLong());
        content = in.readUTF();
    }catch(Exception e){
    }
}

ex. 8

    为能保持Memo类中的Record ID ,增加一个属性。由此,则完成了Memo类。以下程序显示的是完成后的Memo类 。(ex. 9)

import java.io.*;
import java.util.*;


/**
* Memo类
*/
public class Memo {

    private int recId;
    private Date date;
    private String content = "";

    /**********************************
    * 构造函数
    **********************************/
    public Memo(){
        date = new Date();
    }

    public Memo(byte[] data){
        ByteArrayInputStream bais = new ByteArrayInputStream(data);
        DataInputStream in = new DataInputStream(bais);
        try{
            date = new Date(in.readLong());
            content = in.readUTF();
        }catch(Exception e){
        }
    }

    public Memo(String content, Date date) {
        this.content = content;
        this.date = date;
    }


    /*********************************
    * Instance方法
    *********************************/

    /**
    * 变换字节排列
    */
    public byte[] toBytes(){
        byte[] data = null;
        try{
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            DataOutputStream out = new DataOutputStream(baos);

            out.writeLong(date.getTime());
            out.writeUTF(content);
            data = baos.toByteArray();

            baos.close();
            out.close();

        }catch(Exception e){
        }

        return data;
    }

    /**********************************
    * Getter & Setter
    **********************************/

    /**
    * 设定Record ID
    */
    public int getRecId(){
        return recId;
    }

    /**
    * 取得内容
    */
    public String getContent() {
        return content;
    }

    /**
    * 取得最后访问的日期和时间
    */
    public Date getDate() {
        return date;
    }

    /**
    * 设定内容
    */
    public void setContent(String string) {
        content = string;
        date = new Date();
    }

    /**
    * 设定最后访问的日期和时间
    */
    public void setDate(Date date) {
        this.date = date;
    }

    /**
    * 设定Record ID
    */
    public void setRecId(int id){
        this.recId = id;
    }

}

ex. 9

 接下来,开始在MobileMemo类上制作RMS操作吧。RMS操作有如下四种方法。

  • 全部取得Memo内容
  • 重新制作Memo内容
  • 保存Memo内容
  • 清除Memo内容

    全部取得Memo内容的方法中,利用RecordEnumeration全部取得Record,并从取得的Record字节排列中制作Memo对象。制作完成的Memo对象能够将Vector型的memos作为Instance变量加以定义,并在此保持。而且,从Record Store中全部取得完Record 后,则可以按照Record 更新Record Store画面。在此,定义了如下方法。(ex. 10)

/**
// 从Record Store更新信息
*/
public void reloadFromRSM() {
memos.removeAllElements();

// 取得Record
RecordStore rs = null;
RecordEnumeration re = null;
try {
rs = RecordStore.openRecordStore(RS_NAME, true);
re = rs.enumerateRecords(null, null, true);

// 取得Record
while (re.hasNextElement()) {
int id = re.nextRecordId();// 取得Record Id
byte[] data = rs.getRecord(id);// 取得Record
Memo memo = new Memo(data);// 完成Memo
memo.setRecId(id);// 设定Record Id
memos.addElement(memo);// 增加Memo
}

} catch (Exception e) {
} finally {
// 取消RecordEnumeration
if (re != null) {
try {
re.destroy();
} catch (Exception e) {
}
}
// 关闭Record Store
if (rs != null) {
try {
rs.closeRecordStore();
} catch (Exception e) {
}
}
}

// 更新Memo list
initilizeList();
for (int i = 0; i < memos.size(); i++) {
Memo memo = (Memo) memos.elementAt(i);
list.append(memo.getDate().toString(), null);
}

}

ex. 10

    转换到Memo list画面时呼出ex. 10的方法。

    接着,继续记述余下的操作。这些操作主要针对Record store进行更改。即使将每一步操作步骤都详细记述也是没关系的,为了简单化,现在将针对Record store的操作都整合在一个方法中,并记述根据if文的区分处理。(ex. 11)

/**
* 重新制作Memo
*/
public Memo createNewMemo() {
Memo memo = new Memo();
return changeMemoToRMS(memo, add);
}

/**
* 保存Memo内容
*/
public void writeMemo(Memo memo) {
changeMemoToRMS(memo, ok);
}

/**
* 消除Memo
*/
public void deleteMemo(Memo memo) {
changeMemoToRMS(memo, delete);
}

/**
* 在Record Store上反映Memo的变更
*/
private Memo changeMemoToRMS(Memo memo, Command c) {
RecordStore rs = null;
try {
rs = RecordStore.openRecordStore(RS_NAME, true);

// Memo的更改被反映到Record Store
// 依据命令更改操作
if (c == ok) { // memo的编辑
int id = memo.getRecId();
rs.setRecord(id, memo.toBytes(), 0, memo.toBytes().length);
} else if (c == delete) { // 清除Memo
int id = memo.getRecId();
rs.deleteRecord(id);
} else if (c == add) { // 重新制作Memo
int id = rs.addRecord(memo.toBytes(), 0, memo.toBytes().length);
memo.setRecId(id);
}
} catch (Exception e) {
} finally {
if (rs != null) {
try {
rs.closeRecordStore();
return memo;
} catch (Exception e) {
}
}
}
return null;
}

ex. 11

    下面将完成的处理与命令处理结合在一起。(ex. 12)Memo显示画面中显示的Memo内容被保持为名为currentMemo的Instance变量,并且在Memo显示画面中,可以显示currentMemo内容。

/**
* 命令处理
*/
public void commandAction(Command c, Displayable d) {

if (d == list) {
if (c == add) {
// 重新制作Memo
currentMemo = createNewMemo();
} else if (c == show) {
// 取得Memo
int index = list.getSelectedIndex();
if(index == -1)return;
currentMemo = (Memo) memos.elementAt(index);
}

// 转入Memo显示画面
memoText.setString(currentMemo.getContent());
display.setCurrent(memoText);
} else if (d == memoText) {
if (c == ok) {
// RecordMemo内容
currentMemo.setContent(memoText.getString());
writeMemo(currentMemo);
} else if (c == delete) {
// 清除Memo内容
deleteMemo(currentMemo);
}

// 转入Memo list
reloadFromRSM();
display.setCurrent(list);
}
}

ex. 12

 

■ 完成

  本讲中所制作的源码如下所示:

  运行后如下:

 

 

■ 总结

  在本讲中,介绍了利用RMS可以进行数据保存和读取。由于利用这种功能,能够在应用程序内永久保存数据,所以能够制作成高级功能的应用程序。从下讲开始,计划介绍手机网络的有关知识。学习了第一讲[创建开发环境] 到第七讲的[网络],有关手机JAVA的相关技术应该有个大概的轮廓了。以这些基础的JAVA技术信息为基础,一定可以制作成出色的应用程序的!


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值