首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2ME

J2ME 記事本實戰:RMS 持久化、資料加密、MIDlet 完整架構原始碼解析

     編輯:J2ME

專案概覽

作者「mant」實作一款帶密碼保護的手機記事本,核心功能:

  • 記事 CRUD(新增、查看、修改、刪除)
  • RMS (Record Management System) 本地持久化
  • 資料序列化與簡易加密(noteSave.insertCode/readCode)
  • 啟動密碼驗證(首次運行設定密碼,之後需輸入)
  • 記事列表顯示、儲存空間資訊查看

代碼結構:myNote (MIDlet 主類) + noteSave (資料實體/序列化) + passwordSave (密碼管理)。

核心類別設計

1. myNote : MIDlet + CommandListener

關鍵欄位:


private Display display;
private List list;                 // 記事標題列表
private int[] ids;                 // RMS 記錄 ID 陣列
private noteSave ns = new noteSave();
private passwordSave ps = new passwordSave();
private String password;
private TextField tfPassWord;
private int flag = 0;              // 0=有密碼需驗證, 1=首次設定密碼

生命周期:

  • constructor:初始化 Display、讀取密碼、設定 flag
  • startApp():顯示密碼輸入 Form (fPassWord)
  • run():驗證通過後建立主列表 list,載入所有記事

2. 密碼驗證流程


// startApp() 中
fPassWord = new Form("登錄");
tfPassWord = new TextField("", "", 20, TextField.ANY);
if (flag == 1) tfPassWord.setLabel("設置密碼");
else tfPassWord.setLabel("輸入密碼");
// Command "OK" 處理
if (flag == 1) { ps.setPassword(tfPassWord.getString()); run(); }
else if (password.equals(tfPassWord.getString())) { run(); }
else { tfPassWord.setLabel("密碼錯誤"); }

3. RMS 讀寫核心:readAll()


private void readAll() {
    list.deleteAll();
    RecordStore rs = RecordStore.openRecordStore("DB", true);
    RecordEnumeration re = rs.enumerateRecords(null, null, false);
    ids = new int[re.numRecords()];
    int i = 0;
    while (re.hasNextElement()) ids[i++] = re.nextRecordId();
    re.reset(); i = 0;
    while (re.hasNextElement()) {
        byte[] data = re.nextRecord();
        ns.readCode(data);  // 解密/反序列化
        list.append(ns.noteTitle, null);
        i++;
    }
    rs.closeRecordStore();
}

關鍵點:RecordEnumeration 需 reset() 才能重複遍歷;ids 陣列保持索引與 RMS 記錄 ID 對應,供後續修改/刪除使用。

4. 指令處理中樞:commandAction()

巨大的 if-else 鏈處理所有 UI 事件:

  • 添加:顯示標題輸入 Form → 「繼續」 → 內容輸入 TextBox → 「確定」 → save()
  • 查看:讀取選中記錄 ID → read(id) → 顯示內容 TextBox
  • 修改:查看介面按「確定」 → modify() 更新 RMS
  • 刪除:彈出確認 Alert → 「確定」 → delete() 刪除記錄
  • 信息:顯示 RMS 統計(記錄數、可用空間、下一 ID、版本號)
  • 退出/Exit:notifyDestroyed() 終結 MIDlet

5. 資料實體與序列化:noteSave


public class noteSave {
    String noteTitle, noteString;
    
    public byte[] insertCode() {  // 序列化 + 簡易加密
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        DataOutputStream dos = new DataOutputStream(bos);
        dos.writeUTF(noteTitle);
        dos.writeUTF(noteString);
        // 此處可插入加密邏輯:byte[] encrypted = encrypt(bos.toByteArray());
        return bos.toByteArray();
    }
    
    public void readCode(byte[] data) {  // 解密 + 反序列化
        ByteArrayInputStream bis = new ByteArrayInputStream(data);
        DataInputStream dis = new DataInputStream(bis);
        noteTitle = dis.readUTF();
        noteString = dis.readUTF();
    }
    
    public static RecordStore openRSAnyway(String name) {
        if (name.length() > 32) return null; // RMS 名稱長度限制
        return RecordStore.openRecordStore(name, true);
    }
}

架構優化建議(重構方向)

現狀問題建議改進
commandAction 逾 300 行,邏輯混雜拆分為獨立 Command 類、狀態模式、或 MVC Controller
密碼明文儲存 (passwordSave 未見代碼)採用 PBKDF2/BCrypt 雜湊儲存,驗證時比對雜湊值
noteSave 簡易序列化,無真正加密引入 AES-128 (JSR 177 SATSA) 或輕量級 XOR/RC4
RMS 操作分散在 MIDlet 中建立 Repository 類封裝所有 RMS 存取
UI 硬編碼字串,無國際化使用 Resource Bundle (.properties) 分離文案
無異常具體處理,僅 printStackTrace分類處理:儲存滿、資料損毀、權限拒絕,給用戶友好提示

編譯與運行

  1. 建立 J2ME Midlet Suite 專案
  2. 建立 package Window,加入三個類檔案
  3. 專案屬性 → Application Descriptor → MIDlet-1: myNote, /icon.png, Window.myNote
  4. Run As → Emulated J2ME Midlet

結語

這份代碼雖屬「練筆」,卻完整呈現了 J2ME 應用的核心骨架:MIDlet 生命周期、高層 UI (Form/List/TextBox/Alert)、低層 UI (Canvas)、RMS 持久化、事件驅動、資料序列化。對初學者極具參考價值;對資深開發者,則是重構練習的絕佳素材——在 30KB JAR 限制下,如何將 500 行單體拆分為清晰分層架構,是功力的試金石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved