熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

JavaME程序 Run Anywhere-- 利用反射機制來動態加載聲

2013-11-23 19:25:26  來源: Java核心技術 
    讓JavaME程序 Run Anywhere 利用反射機制來動態加載聲音API 歡迎指教 tcn Write oncerun anywhere 是JAVA的口號但在JME平台上做的應用要想不改動代碼就run anywhere難度是很大的如果要把一個應用程序做到讓大多數的機型都適用就讓JavaME程序 Run Anywhere
    利用反射機制來動態加載聲音API
    Write oncerun anywhere 是JAVA的口號但在JME平台上做的應用要想不改動代碼就run anywhere難度是很大的如果要把一個應用程序做到讓大多數的機型都適用就要考慮到方方面面其難度是相當大的
    比如給百寶箱做游戲上線機型大多是MIDP的機器感覺移植中最麻煩的還要數聲音部分的API必須根據各個機型來改動雖然圖象還比較容易做成自適應的但聲音部分就一般就只能根據各個機型來改動
    下面提供一種解決方案可以讓JME程序在運行時自動加載該機型支持的聲音資源並用該機型的聲音API來播放
    關鍵問題 各機型提供的播放音樂的API都有所不同特別是較老的機型需要在運行時根據機型自動加載
    各機型支持的聲音的資源文件也不同需要在運行時根據機型自動加載
    各機型的JVM不同多多少少有一些比較特別的BUG
  解決方案 原則能用標准API就用標准API不能用的話就用各個機型自身的API
    // Player types
    static final int STANDARD = ; //For MIDI
    static final int NOKIA = ; //For ott
    static final int SAMSUNG = ; //For mmf
    static final int NEC = ; //For MIDI
    static final String[] supportedPlayerTypes = {
    jadiaPlayer //STANDARD API
    comnokiamidsoundSound // Nokia
    comsamsungutilAudioClip //samsung
    diaAudioClip //nec
    };
    下面利用反射機制來動態加載
    public void determinePlayerType() {
    // use most > less use
    isSupportSound = true;
    for (int i = ; i < supportedPlayerTypeslength; i ) {
    // try to load a proper sound Player
    try {
    ClassforName(supportedPlayerTypes[i]); //加載當前的Player類型
    playerType = i; //保存加載成功的類的類型
    return;
    } catch (Exception e) { //加載不成功說明不支持繼續加載下一種
    eprintStackTrace();
    }
    }
    isSupportSound = false;
    }
    下面就可以根據在載成功的類型來加載可以播放的聲音資源了
    public void createPlayer(String name) {
    if (!isSupportSound)
    return;
    switch (playerType) {
    case STANDARD: // for MIDI
    case NEC:
    createPlayerFactory(/ name mid);
    break;
    case NOKIA: //for ott
    createPlayerFactory(/ name ott);
    break;
    case SAMSUNG: // for mmf
    createPlayerFactory(/ name mmf);
    break;
    }
    }


    對各個機型特有的BUG是沒有什麼特別好的辦法的只能各個機型調試這只能怪廠商了
    該方案優點在移植的時候就不用改動代碼只要在相應的機型JAR包中保留相關的資源就可以了這樣就不用為了各個機型都折騰一遍了
    注意 用 SystemgetProperty(microeditionplatform)來確定機型是不保險的因為有的機型只是簡單地返回JME platform
    遺留問題
    NecN 在運行 ClassforName(jadiaPlayer);時候會立刻報應用程序出錯而不是拋出ClassNotFoundException異常這是該機型JVM的特性(BUG)所以給NecN的代碼中必須注釋掉jadiaPlayer的一切信息這就得改動代碼有違我們的初衷的確是個遺憾(估計NEC的機型都素這樣的)
    這個類還有待擴展以支持更多機型並加入震動部分的API理論上可以包含所有的機型但實際應用中只要包含需要用到的機型相關API就可以了
    測試機型 在 三星EMOTOVNOKIA NecN(注釋掉jadiaPlayer相關內容)上均測試通過
    下面是源程序
    /**
    * Created on
    * This class is mainly for the games on various mobile platform
    * If U have any good ideas about the JME contact me at tcn
    *
    * Version
    */
    import javaxmicroeditionlcdui*;
    import javaio*;
    //********************* STANDARD ***********************
    import jadia*;
    //********************* NOKIA ***********************
    import comnokiamidsound*;
    //********************* SAMSUNG ***********************
    import comsamsungutil*;
    // ********************* NEC ***********************
    import dia*;
    //********************* SonyEricsson ***********************
    // the same as JME standard API
    /**
    * @author IntoTheDream
    */
    public class MyPlayer {
    private static MyPlayer mp = null;
    //Sound types to be enlarged
    static final int MIDI = ;
    static final int MMF = ;
    static final int OTT = ;
    // Player types
    static final int STANDARD = ; //For MIDI
    static final int NOKIA = ; //For ott
    static final int SAMSUNG = ; //For mmf
    static final int NEC = ; //For MIDI
    static final String[] supportedSoundTypes = { mid mmf ott };
    private static int soundType;
    static final String[] supportedPlayerTypes = {
    jadiaPlayer //must be dimissed for NECN
    comnokiamidsoundSound comsamsungutilAudioClip
    diaAudioClip };
    private static int playerType;
    // Note : first play sound to determine whether sound On or Off
    // Of course you can change it in the game
    static boolean isSupportSound;
    static boolean isSoundOn = true;
    // ********************* STANDARD ***********************
    Player player;
    // ********************* NOKIA ***********************
    Sound nokiaPlayer;
    // ********************* SAMSUNG ***********************
    comsamsungutilAudioClip samsungPlayer;
    // ********************* NEC ***********************
    diaAudioClip necPlayer;
    // singleton
    private MyPlayer() {
    }
    public static MyPlayer getMyPlayer() {
    if (mp == null) {
    mp = new MyPlayer();
    mpdeterminePlayerType();
    }
    return mp;
    }
    // automatically run this first !!
    public void determinePlayerType() {
    // use most > less use
    isSupportSound = true;
    for (int i = ; i < supportedPlayerTypeslength; i ) {
    // try to load a proper sound Player
    try {
    ClassforName(supportedPlayerTypes[i]);
    playerType = i;
    return;
    } catch (Exception e) {
    eprintStackTrace();
    }
    }
    isSupportSound = false;
    }
    public void createPlayer(String name) {
    if (!isSupportSound)
    return;
    switch (playerType) {
    case STANDARD: // for MIDI
    case NEC:
    createPlayerFactory(/ name mid);
    break;
    case NOKIA: //for ott
    createPlayerFactory(/ name ott);
    break;
    case SAMSUNG: // for mmf
    createPlayerFactory(/ name mmf);
    break;
    }
    }


    private void createPlayerFactory(String url) {
    if (isSupportSound && isSoundOn) {
    try {
    InputStream is;
    switch (playerType) {
    case NEC:
    necPlayer = MediagetAudioClip(url);
    break;
    case STANDARD: //must be dimissed for NECN
    is = thisgetClass()getResourceAsStream(url);
    player = ManagercreatePlayer(is audio/midi);
    break;
    case NOKIA:
    is = thisgetClass()getResourceAsStream(url);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    for (int b = isread(); b >= ; b = isread()) {
    baoswrite(b);
    }
    nokiaPlayer = new comnokiamidsoundSound(baos
    toByteArray()
    comnokiamidsoundSoundFORMAT_TONE);
    break;
    case SAMSUNG:
    samsungPlayer = new comsamsungutilAudioClip(
    comsamsungutilAudioClipTYPE_MMF url);
    break;
    }
    } catch (Exception e) {
    eprintStackTrace();
    }
    }
    }
    public void play(int loop) {
    if (isSupportSound && isSoundOn) {
    try {
    switch (playerType) {
    case NEC:
    if (necPlayer == null)
    break;
    necPlayersetLoopCount(loop);
    necPlayerplay();
    break;
    case STANDARD: //must be dimissed for NECN
    if (player == null)
    break;
    playersetLoopCount(loop);
    playerstart();
    break;
    case NOKIA:
    if (nokiaPlayer == null)
    break;
    nokiaPlayerplay(loop);
    break;
    case SAMSUNG:
    if (samsungPlayer == null)
    break;
    samsungPlayerplay(loop ); // is volume
    break;
    }
    } catch (Exception e) {
    eprintStackTrace();
    }
    }
    }
    public void stopSound() {
    if (isSupportSound && isSoundOn) {
    try {
    switch (playerType) {
    case STANDARD: //must be dimissed for NECN
    if (player == null)
    break;
    playerdeallocate();
    playerstop();
    playerclose();
    player = null;
    break;
    case NOKIA:
    if (nokiaPlayer == null)
    break;
    nokiaPlayerstop();
    nokiaPlayer = null;
    break;
    case SAMSUNG:
    if (samsungPlayer == null)
    break;
    samsungPlayerstop();
    samsungPlayer = null;
    break;
    case NEC:
    if (necPlayer == null)
    break;
    necPlayerstop();
    necPlayer = null;
    break;
    }
    Systemgc();
    } catch (Exception e) {
    eprintStackTrace();
    }
    }
    }
    }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/26841.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.