MIDlet 的三大狀態 —— Paused(停止)、Active(激活)、Destroyed(銷毀) —— 只能由應用程序管理器(AMS) 觸發轉換。MIDlet 自身調用 startApp/pauseApp/destroyApp 不會改變狀態,僅作為回調入口。
[啟動] --> (AMS) --> [Paused] --(AMS 調用 startApp)--> [Active]
^ |
| v
(AMS 調用 pauseApp) (AMS 調用 destroyApp)
| |
+---------- [Destroyed] <--- (AMS 強制銷毀)
| 方法 | 調用者 | 語義 | 常見誤區 |
|---|---|---|---|
startApp() | AMS | 進入 Active 狀態,**每次從 Paused 恢復都會調用** | ❌ 放一次性初始化代碼 → 重複執行 |
pauseApp() | AMS | 即將進入 Paused,**釋放佔用資源(網絡、線程、音頻)** | ❌ 忽略釋放 → 來電時資源洩漏 |
destroyApp(boolean unconditional) | AMS | 即將銷毀,**最後釋放、持久化存檔**;unconditional=true 表示強制銷毀,必須返回 | ❌ 拋異常阻止銷毀 → AMS 強制殺進程 |
// 請求激活(如後台下載完成喚醒前台)
resumeRequest();
// 通知 AMS 我願意進入 Paused(如用戶按掛機鍵)
notifyPaused(); // 不會觸發 pauseApp()!
// 通知 AMS 我已準備好銷毀
notifyDestroyed(); // 不會觸發 destroyApp()!
最佳實踐:主動請求前先手動調用對應回調,確保邏輯一致:
// 正確的主動退出流程
public void exitGame() {
destroyApp(true); // 先執行清理邏輯
notifyDestroyed(); // 再請求 AMS 銷毀
}
| 場景 | AMS 行為 | MIDlet 應對 |
|---|---|---|
| 用戶啟動應用 | 構造器 → Paused → startApp() | 構造器做重初始化,startApp 顯示主畫面 |
| 來電中斷 | pauseApp() → Paused | 釋放音頻、網絡、暫停遊戲邏輯線程 |
| 通話結束返回 | startApp() → Active | 恢復音頻、重連網絡、恢復遊戲循環 |
| 用戶按紅鍵掛機 | pauseApp() → Paused → destroyApp(false) → Destroyed | destroyApp 存檔、關閉連接、釋放所有資源 |
| 系統低內存強殺 | destroyApp(true) → Destroyed(不保證調用 pauseApp) | destroyApp 必須快速返回,無阻塞操作 |
構造器一次,startApp 多次;
pauseApp 放資源,destroyApp 存檔;
主動請求先回調,AMS 掌生殺大權。