MTK 平台普及後,J2ME 虛擬機品牌爆發(JBlend、Sony Ericsson、Nokia S40/S60、Moto、三星、LG 等),「Write Once, Run Anywhere」淪為「Write Once, Debug Everywhere」。本文系統整理主流虛擬機特性、JCP/JSR 體系、系統屬性檢測代碼、應用屬性讀取、完整環境探測 Demo,構建「編譯期適配 + 運行期檢測 + 優雅降級」的高可移植開發體系。
主流虛擬機平台速覽
| 平台 | 特點 | 官方資源 |
| JBlend | 日本 Aplix,廣泛用於 MTK、Moto 低端機 | aplixcorp.com |
| Sony Ericsson | Java Platform v8,穩定性最佳、API Bug 少、網絡無洩漏 | developer.sonyericsson.com |
| Nokia S40 | 低端機主流,相對完善,並發連接數有限制 | forum.nokia.com |
| Nokia S60 | 智能機,功能豐富但有特殊用法(如系統屬性鍵值不同) | forum.nokia.com |
JCP / JSR 體系速查
JCP (Java Community Process) 維護 Java 規範;JSR (Java Specification Request) 為具體提案。關鍵 JSR:
| JSR | 名稱 | 核心內容 |
| 118 | MIDP 2.1 | UI、RMS、網絡、多媒體 |
| 82 | Bluetooth | 藍牙 API |
| 135 | MMAPI | 多媒體播放/錄製 |
| 172 | Web Services | JAXP/JAX-RPC 子集 |
| 75 | PIM & FileConnection | 聯繫人/行程/文件系統 |
| 177 | SATSA | 智慧卡/加密/PKI |
| 211 | CHAPI | 內容處理器調用 |
| 239 | OpenGL ES | 3D 圖形 |
| 179 | Location | LBS 定位 |
| 180 | SIP | VoIP 信令 |
| 184 | M3G | 3D 圖形場景圖 |
| 229 | Payment | 手機支付 |
| 234 | AMMS | 進階多媒體 |
| 238 | I18N | 國際化 |
| 248 | MSA | 移動服務架構(JSR 集合基線) |
運行期 JSR/特性檢測兩大法
1. System.getProperty(key)
String val = System.getProperty("microedition.profiles"); // "MIDP-2.0"
String val = System.getProperty("microedition.m3g.version"); // "1.0" 或 null
2. Class.forName(className)
boolean hasMMAPI = false;
try { Class.forName("javax.microedition.media.control.VideoControl"); hasMMAPI = true; }
catch (ClassNotFoundException e) {}
核心系統屬性鍵值表(節選)
| 屬性鍵 | 含義 | 典型值 |
| microedition.platform | 平台標識 | j2me |
| microedition.configuration | CLDC 版本 | CLDC-1.1 |
| microedition.profiles | MIDP 版本 | MIDP-2.0 |
| microedition.locale | 語言環境 | zh_CN |
| microedition.pim.version | JSR 75 PIM | 1.0 |
| microedition.location.version | JSR 179 | 1.0 |
| microedition.m3g.version | JSR 184 | 1.0 |
| com.nokia.mid.imei | Nokia IMEI | 35xxxxxxxxxxxxx |
| com.nokia.mid.cellid | Nokia Cell ID | xxxx |
| com.sonyericsson.imei | SE IMEI | 35xxxxxxxxxxxxx |
| supports.mixing | MMAPI 混音 | true/false |
| audio.encodings | 支援音頻格式 | encoding=audio/wav encoding=audio/amr |
| fileconn.dir.photos | JSR 75 圖片目錄 | file:///c:/My files/Images/ |
應用屬性 (JAD/Manifest) 讀取
// JAD 中自定義屬性
Which-Locale: en
// 代碼讀取
String locale = getAppProperty("Which-Locale"); // 大小寫敏感,不存在回傳 null
完整環境探測 Demo 代碼(核心片段)
private void getSysInfo() {
addInfo("Config", getProp("microedition.configuration"));
addInfo("Profile", getProp("microedition.profiles"));
addInfo("Platform", getProp("microedition.platform"));
addInfo("JTWI", getProp("microedition.jtwi.version"));
addInfo("M3G", getProp("microedition.m3g.version"));
addInfo("Location", getProp("microedition.location.version"));
addInfo("PIM", getProp("microedition.pim.version"));
addInfo("Bluetooth", hasClass("javax.bluetooth.DiscoveryAgent") ? "yes" : "no");
addInfo("WMA 2.0", hasClass("javax.wireless.messaging.MultipartMessage") ? "yes" : "no");
addInfo("MMAPI", hasClass("javax.microedition.media.control.VideoControl") ? "yes" : "no");
addInfo("FileConn", hasClass("javax.microedition.io.file.FileSystemRegistry") ? "yes" : "no");
addInfo("CHAPI", getProp("CHAPI-Version"));
addInfo("Nokia UI", hasClass("com.nokia.mid.ui.FullCanvas") ? "yes" : "no");
addInfo("Siemens Ext", hasClass("com.siemens.mp.MIDlet") ? "yes" : "no");
// ... 更多檢測
addInfo("Total Mem", Runtime.getRuntime().totalMemory() + " bytes");
addInfo("Free Mem", Runtime.getRuntime().freeMemory() + " bytes");
}
private String getProp(String key) {
String v = System.getProperty(key);
return (v == null) ? "" : v;
}
private boolean hasClass(String name) {
try { Class.forName(name); return true; } catch (Exception e) { return false; }
}
private void addInfo(String name, String value) {
form.append(new StringItem(name, value));
}
適配策略三層架構
- 編譯期適配:J2ME Polish / Ant 預處理,針對不同廠商產出差異 JAR(如 IMEI 獲取鍵值、全螢幕 API)。
- 運行期檢測:啟動時執行上述探測,將能力標記緩存至
DeviceCapabilities 單例。
- 優雅降級:核心功能接口化,提供
DefaultImpl、NokiaImpl、MotoImpl 等策略類,工廠根據檢測結果注入。缺失特性時回退至基礎實現或隱藏對應功能入口。
避坑清單
- 系統屬性鍵值大小寫敏感,Nokia/SE/Moto 各有私有前綴。
Class.forName 捕獲 ClassNotFoundException 而非泛 Exception,避免掩蓋 NoClassDefFoundError。
- JAD 自定義屬性名建議加前綴 (如
MyApp-) 避免衝突。
- 實機測試矩陣:至少覆蓋 S40 v1/v2、S60 MIDP1/2、Moto JBlend/非 JBlend、SE JP-7/JP-8、MTK 主流晶片。
- 簽名域 (Trusted/Manufacturer) 享有更高 API 存取權,未簽名測試結果不可作為最終依據。
結語
高可移植非一日之功,需建立「虛擬機特性資料庫 → 自動化探測 → 策略模式適配 → 持續實機回歸」的工程化流程。本文提供的屬性表、檢測代碼、適配架構可作為團隊基礎設施的起點。
- 上一篇文章: J2ME/MIDP 圖像任意角度旋轉算法完整實現:數學原理、定點數移植、Sprite 整合與替代方案
- 下一篇文章: J2ME 手機開發環境完整搭建指南:從 JDK 到 Eclipse 整合
Copyright ©
程式碼之家 All Rights Reserved