非遊戲類 MIDP 應用常面對多 Screen/Canvas 切換需求。傳統 MVC 雖完整但過重:Controller 膨脹、所有 View 啟動時初始化佔記憶體、Model 過度設計。本文提出**基於堆疊的輕量導航模型**,僅保留核心靈活性,完美適合「前進/後退」規律的螢幕流程。
public class ControllerMIDlet extends MIDlet {
private static ControllerMIDlet instance = null;
private Display display = null;
private Stack ui = new Stack(); // 螢幕堆疊
public ControllerMIDlet() { instance = this; }
protected void startApp() {}
protected void pauseApp() {}
protected void destroyApp(boolean unconditional) {}
// 後退:彈出當前,顯示新堆疊頂
public static void goBack() {
instance.ui.pop();
Object obj = instance.ui.peek();
instance.display.setCurrent((Displayable) obj);
}
// 前進:推入新螢幕並顯示
public static void forward(Displayable next) {
instance.ui.push(next);
instance.display.setCurrent(next);
}
}
靜態 instance 讓任意處呼叫 ControllerMIDlet.forward()/goBack() 無需傳遞 MIDlet 參考。

主選單 → Help → 返回主選單。直接用 forward()/goBack()。

列表 → **載入中** → 圖片詳情。若用戶在詳情頁按「返回」,應回列表而非載入中頁。**解決:`replace()` 取代 `forward()`**
public static void replace(Displayable next) {
instance.ui.pop(); // 移除載入中頁
instance.ui.push(next); // 推入詳情頁
instance.display.setCurrent(next);
}
堆疊變化:

選擇自動登入:

登入頁 → 自動登入處理 → 主選單 (登入頁隱藏不顯示)
不選自動登入:

登入頁 → 手動登入 → 主選單
解決:雙參數 `forward(d1, d2)` — 兩者都入堆疊,只顯示 d2
public static void forward(Displayable d1, Displayable d2) {
instance.ui.push(d1); // 登入頁入棧但不顯示
instance.ui.push(d2); // 主選單入棧並顯示
instance.display.setCurrent(d2);
}
返回時:取消 → 回登入頁;確認 → 留主選單。完美支援條件分支。
| 優點 | 缺點 |
|---|---|
| 極簡輕量,無 Controller 膨脹問題 | 資料由各螢幕分散處理,後續螢幕建構子參數可能越來越多 |
| 按需建立螢幕,啟動快、記憶體省 | 複雜資料流需手動傳遞,無集中 Model 管理 |
| 返回時狀態完整保留 (堆疊特性) | 不支援任意跳轉 (非線性流程) |
| 擴展方法靈活應對分支/替換場景 | 全域靜態 instance 難以單元測試 |
文中預告後續將整合「多執行緒等待螢幕」完整方案,讓應用層完全不用處理聯網非同步邏輯,專注業務。核心思路:
堆疊導航模型以 **MIDlet 單例 + Stackforward/goBack/replace/forward(d1,d2) 四大操作,以最小代價解決 90% MIDP 應用的螢幕導航需求。適合規律性前進/後退流程,資料傳遞複雜度較高時可考慮引入輕量 Context 物件在堆疊中傳遞。