2011-11-26 37 views
1

我有一個有趣的情況與Android MediaPlayer。我有大約30種聲音需要在活動中播放。我得到奇怪的結果,我不知道是否來自內存問題或不...Android媒體播放器懸掛或返回null

我需要使用媒體播放器的原因是,我有一個定時流動的聲音,其中一個聲音需要按照一定的順序依次玩。我也使用回調來查看下一個播放的聲音。因此,soundpool是出...

我試過將每個聲音加載到它自己的媒體播放器使用MediaPlayer.create()。現在,這款Samsung Galaxy S Vibrant設備可以正常工作。然而,當我嘗試設置onCompletionListener時,我的三星Ace的客戶端正在獲取空指針異常,這意味着.create()在他的設備上返回null,但不是我的。

所以,我從加載它們一次全部切換到以前的聲音using this method

這類工程的onCompletionListener,加載它們在飛行拳頭3-4聲音播放,然後將其掛在我客戶端設備(在我的設備上仍能正常工作)。我假設它掛在.prepare()

這非常難以理清,因爲我的客戶端沒有真正的logcat知識,也沒有SDK來調試,並且它在我的設備上工作正常。它甚至掛在他的第二個與我的模型相同的設備上。

任何人都知道什麼可能會導致這個或如何調試它?

我在想我的下一步將只是使用一個MediaPlayer並使用OnCompletionListener的mp參數在同一個媒體播放器上加載下一個聲音。我會發布我的發現。

回答

1

所以,它一定是某種內存問題。我最初有20多個媒體播放器加載。

現在我將它們全部組合到一個媒體播放器中,並動態加載聲音。聲音很小,所以我不擔心加載時間。

這裏有一些幫手代碼,以防萬一任何人想要它。

private MediaPlayer getMediaPlayer(MediaPlayer mp, int resID, OnCompletionListener listener){ 
mp.release(); 
mp = null; 
mp = new MediaPlayer(); 
AssetFileDescriptor afd = getResources().openRawResourceFd(resID); 
try { 
    mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength()); 
    mp.prepare(); 
    mp.setOnCompletionListener(listener); 
} catch (IllegalArgumentException e) { 
    e.printStackTrace(); 
} catch (IllegalStateException e) { 
    e.printStackTrace(); 
} catch (IOException e) { 
    e.printStackTrace(); 
} 
return mp; 
} 

我使用它來加載一個新的聲音。它有一點點的開銷,但它有效,這是重要的。

以下是我如何使用它。

mSoundPlayer = getMediaPlayer(mSoundPlayer, R.raw.a123switch, endSwitch123Listener); 
mSoundPlayer.start(); 
1

如果您正確釋放媒體播放器,它不應該是內存問題。你可以適當地確保這一點做:

if(mediaplayer!=null){ 
     if(mediaplayer.isPlaying()){ 
      mediaplayer.stop(); 
     } 
     mediaplayer.release(); 
     mediaplayer = null; 
} 

我相信這是一個10MB的限制(最小,有的手機是更高版本)APK內存分配,所以你應該能夠檢查這個適合你的範圍之內。不過,市場將允許高達50MB。

對於調試,我建議你確保所有的聲明都在那裏(聽起來很愚蠢,但它排除了),因爲如果你錯過了聲音文件,它當然無法創建。如果拋出異常,則創建Toast通知IllegalStateException將確保您管理媒體播放器狀態不成問題。

還值得一提的是,你不應該混合preparecreate。如果您使用的是create,則它將會呼叫prepare,隨後對prepare的呼叫可能會導致奇怪的行爲;不知道它是否會使玩家無效!

一般而言,您不想按照您的建議(創建新媒體播放器並更改onComplete中的聲音)進行。原因很簡單,當你撥打createprepare時,它會將聲音加載到內存中 - 這需要花費不同的時間,這取決於手機(對於某些手機來說這可能是一段非常長的時間!)。一次加載它們會更好。

+0

感謝您的基本檢查。我知道有時候最簡單的解決方案可能是對的。但不是在這種情況下:) 我不混合創建和準備。我試圖創建它們,最終在某個時候給了我一個從.create()返回的空值。 –

+0

感謝您的幫助,我的方法結束了工作,併發布它作爲答案,我雖然你有+1。 –