本範例展示一個基於 MIDP 2.0 + LCDUI 的排行榜客戶端,採用 主 MIDlet + 背景執行緒 + GameCanvas 自繪 的經典架構,實現 HTTP GET 請求、資料解析與排名顯示完整流程。
startApp、pauseApp、destroyApp)Display 參考與主表單(Form)Command),觸發背景執行緒啟動網路請求Chang(String) 回調供網路模組切換顯示畫面採用 GameCanvas 雙緩衝機制(super(true)),在獨立執行緒執行網路操作,避免阻塞事件派發執行緒(EDT)。
HttpConnection hc = (HttpConnection) Connector.open(url);
DataInputStream dis = hc.openDataInputStream();
byte[] buffer = new byte[(int) hc.getLength()];
dis.read(buffer);
String response = new String(buffer);
注意:hc.getLength() 可能返回 -1(Chunked 編碼),生產環境應改用迴圈讀取至 EOF。
伺服器回傳格式假設為:名次&玩家名稱&分數$名次&玩家名稱&分數$...<Html>
<Html> 前的有效資料區段$ 分割各筆排名記錄& 分割欄位自訂 split(String, String) 方法實現字串分割(MIDP 無 String.split()),使用 Vector 動態收集結果再轉陣列。
Graphics g = getGraphics();
Font font = Font.getFont(Font.FACE_MONOSPACE, Font.STYLE_BOLD, Font.SIZE_LARGE);
g.setFont(font);
g.setColor(0, 0, 0);
g.drawRect(0, 0, getWidth(), getHeight()); // 邊框
// 逐行繪製排名文字
g.drawString(rank + " " + playerName + " " + score, x, y, Graphics.HCENTER | Graphics.TOP);
flushGraphics(); // 雙緩衝刷新
| 現狀問題 | 建議改進 |
|---|---|
| 硬編碼伺服器 IP/URL | 外部化至 JAD 屬性或資源檔,支援多環境部署 |
| 同步阻塞 I/O 在執行緒中 | 可接受,但建議加入連線/讀取逾時設定(hc.setRequestProperty) |
| 解析邏輯脆弱(依賴特定分隔符) | 改用 JSON/CSV 結構化格式,或至少定義協議常數 |
| 缺乏網路錯誤重試與使用者提示 | 加入重試機制、錯誤代碼映射至友善訊息 |
| 未釋放連線資源(finally 區塊缺失) | 務必在 finally 關閉 dis、hc |
此範例展示了 J2ME 時代典型的「同步阻塞 HTTP + 執行緒 + 自繪 UI」開發模式。雖然技術棧已歷史性退場,但其核心思想——主執行緒非阻塞、資源確定性釋放、協議解析容錯——在現代行動開發(OkHttp + Coroutines/Flow、Retrofit + RxJava)中依然通用。