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

J2ME 反射機制動態加載聲音 API:解決多機型音頻兼容性難題

     編輯:J2ME

痛點背景

早期 J2ME 手機(MIDP 1.0 為主)音頻 API 極度碎片化:Nokia 用 OTT、Samsung 用 MMF、NEC 自有 API、標準 MIDP 2.0 用 MIDI。硬編碼導致每機型必須維護獨立代碼分支,移植成本極高。

解決方案:運行時反射檢測 + 策略模式

核心類設計

public class MyPlayer {
    // 播放器類型常量
    static final int STANDARD = 0; // MIDI
    static final int NOKIA = 1;    // OTT
    static final int SAMSUNG = 2;  // MMF
    static final int NEC = 3;      // MIDI

    // 按優先級排序的播放器類全名
    static final String[] supportedPlayerTypes = {
        "javax.microedition.media.Player",   // 標準 API
        "com.nokia.mid.sound.Sound",         // Nokia
        "com.samsung.util.AudioClip",        // Samsung
        "com.nec.media.AudioClip"            // NEC
    };

    // 對應音頻文件後綴
    static final String[] supportedSoundTypes = {"mid", "mmf", "ott"};

    private static MyPlayer mp = null;
    private static int playerType;
    private static boolean isSupportSound = true;
    private static boolean isSoundOn = true;

    // 各平台播放器實例
    private Player player;           // Standard
    private Sound nokiaPlayer;       // Nokia
    private com.samsung.util.AudioClip samsungPlayer;
    private com.nec.media.AudioClip necPlayer;
}

動態檢測邏輯

public void determinePlayerType() {
    isSupportSound = true;
    for (int i = 0; i < supportedPlayerTypes.length; i++) {
        try {
            Class.forName(supportedPlayerTypes[i]); // 反射加載
            playerType = i;                         // 記錄成功類型
            return;                                 // 找到即返回
        } catch (Exception e) {
            e.printStackTrace(); // 繼續嘗試下一個
        }
    }
    isSupportSound = false; // 全部失敗
}

統一創建/播放/停止介面

public void createPlayer(String name) {
    if (!isSupportSound) return;
    switch (playerType) {
        case STANDARD: case NEC:
            createPlayerFactory("/" + name + ".mid"); break;
        case NOKIA:
            createPlayerFactory("/" + name + ".ott"); break;
        case SAMSUNG:
            createPlayerFactory("/" + name + ".mmf"); break;
    }
}

private void createPlayerFactory(String url) {
    // 各平台差異化實例化邏輯
    // Standard: Manager.createPlayer(is, "audio/midi")
    // Nokia: Sound(byte[], FORMAT_TONE)
    // Samsung: new AudioClip(TYPE_MMF, url)
    // NEC: Media.getAudioClip(url)
}

public void play(int loop) { /* 統一委派各平台 play */ }
public void stopSound() { /* 統一委派各平台 stop + gc */ }

關鍵優勢

  • 零代碼修改移植:只需在 JAR 中放入對應格式音頻資源
  • 優先級可控:數組順序決定優先使用哪種 API
  • 單例模式:全局唯一聲音管理器

已知限制與規避

擴展方向

  • 增加震動 API 統一封裝
  • 支援更多廠商 API(Moto、Siemens、Sony Ericsson 等)
  • 音頻池化管理,減少重複加載開銷

測試驗證機型

三星 E708、Moto V600、Nokia 7650、NEC N820(需調整)均通過測試。

編譯提示

將各廠商 API 包作為 Library 加入 Eclipse/IDE 專案,預驗證階段不打包進 JAR,運行時由手機系統提供。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題現象規避方案
NEC N820 JVM Bug載入標準 Player 類直接崩潰,不拋 ClassNotFoundException針對 NEC 專版註釋掉標準 Player 相關代碼,或調整檢測順序將 NEC 放在前面
機型識別不可靠System.getProperty("microedition.platform") 返回通用字串完全依賴反射檢測 API 存在性,不依賴機型字串