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

J2ME MIDlet 生命週期完全掌握:狀態轉換與 AMS 交互實戰

     編輯:J2ME

前言:誰在掌控你的 MIDlet?

每個 MIDlet 的出生、暫停、銷毀,都由設備上的 Application Management Software (AMS) 統一調度。作為開發者,我們不直接控制狀態流轉,而是通過重寫三個核心回調方法、並在適當時機主動通知 AMS,來實現與系統的協作。

一、 三大被動回調:AMS → MIDlet

方法觸發時機典型職責
startApp()MIDlet 首次啟動、或從 Paused 恢復初始化資源、顯示主界面 Display.setCurrent()
pauseApp()來電、短信、用戶切換任務等系統搶佔釋放非必需資源(網絡連接、線程、音頻)、暫停遊戲邏輯
destroyApp(boolean unconditional)用戶退出、AMS 強制終止持久化數據、關閉 RecordStore、停止所有線程、釋放所有資源

注意:destroyApp(true) 表示無條件銷毀,必須返回;false 允許拋出 MIDletStateChangeException 請求繼續運行(罕見)。

二、 三大主動通知:MIDlet → AMS

三、 狀態機圖解

[Not Exist] --AMS create--> [Paused] --startApp()--> [Active]
     ^                          |                     |
     |                          v                     |
     +---- destroyApp() -- [Destroyed]                |
            (notifyDestroyed)                         |
                   ^                                  |
                   |---- pauseApp() -- (notifyPaused) |
                   |                                  |
                   +---- resumeRequest() -------------+

四、 實戰代碼範本

public class LifeCycleDemo extends MIDlet implements CommandListener {
    private Display display;
    private Form mainForm;
    private StringBuffer log = new StringBuffer(); // 記錄狀態流轉

    protected void startApp() {
        log.append("→ startApp()\n");
        if (mainForm == null) initUI();
        display.setCurrent(mainForm);
    }

    protected void pauseApp() {
        log.append("→ pauseApp()\n");
        // 釋放佔用資源:停止動畫線程、關閉網絡連接等
    }

    protected void destroyApp(boolean unconditional) {
        log.append("→ destroyApp(" + unconditional + ")\n");
        // 保存設置、關閉 RMS、停止所有線程
    }

    // 用戶點擊「退出」命令
    public void commandAction(Command c, Displayable d) {
        if (c.getCommandType() == Command.EXIT) {
            destroyApp(true);
            notifyDestroyed(); // 必須成對調用
        }
    }
    // ... 其餘代碼省略
}

五、 實測陷阱:來電不一定觸發 pauseApp()

規範規定來電時 AMS 應調用 pauseApp(),但實測中部分廠商實現(如早期 Nokia S40)可能直接銷毀 MIDlet 或完全不回調。防禦性編程建議:

  • 在 startApp() 中做冪等初始化,允許重複調用。
  • 關鍵數據實時持久化(RMS),不依賴 destroyApp() 才保存。
  • 避免在 pauseApp() 執行耗時操作,以免阻塞系統處理來電。

六、 多任務協作最佳實踐

  1. 資源獲取即用即釋:網絡連接、輸入流、RecordStore 用完立即 close()。
  2. 後台線程必須可中斷:保留 volatile boolean running 標誌,pauseApp() 置 false,run() 循環檢測退出。
  3. UI 狀態保存:記住當前顯示的 Displayable、滾動位置、輸入框內容,startApp() 恢復。
  4. 善用 resumeRequest():後台下載完成、推送消息到達時調用,請求回前台提醒用戶。

七、 總結

MIDlet 生命週期管理的核心是「被動回調 + 主動通知」的雙向契約。深理解狀態機、預判廠商差異、編寫健壯的資源釋放邏輯,是打造穩定、良民 J2ME 應用的必修課。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
方法用途調用後果
notifyDestroyed()宣告 MIDlet 已結束AMS 回收資源,進程終止
notifyPaused()請求進入 Paused 狀態AMS 稍後調用 pauseApp(),MIDlet 不再佔用前台
resumeRequest()請求從 Paused 恢復為 ActiveAMS 評估資源後調用 startApp()