2

在我的活動我有以下幾點:我的代碼是否足以防止MediaPlayer泄漏?

private Set<MediaPlayer> mediaPlayers; 

public void onSomeEventInMyActivity() 
{ 
    // play sound 
    MediaPlayer mediaPlayer = MediaPlayer.create(this, R.raw.my_sound); 
    mediaPlayers.add(mediaPlayer); 
    mediaPlayer.setOnCompletionListener(new OnCompletionListener() 
    { 
     @Override 
     public void onCompletion(MediaPlayer mp) 
     { 
      mp.release(); 
      mediaPlayers.remove(mp); 
     } 
    }); 
    mediaPlayer.start(); 
} 

@Override 
protected void onStart() 
{ 
    super.onStart(); 

    mediaPlayers = new HashSet<MediaPlayer>(); 
} 

@Override 
protected void onStop() 
{ 
    super.onStop(); 

    for (MediaPlayer mediaPlayer : mediaPlayers) 
    { 
     if (mediaPlayer.isPlaying()) 
     { 
      mediaPlayer.stop(); 
     } 
     mediaPlayer.release(); 
    } 
} 

這段代碼足夠,還是會導致MediaPlayer的泄漏?是否需要onStoponStart的實現,或者我可以僅僅依靠在onCompletion中調用release

我這樣做了我的代碼,因爲我假設onStop()可以在MediaPlayer播放時調用,所以我需要調用release,因爲onCompletion不會被調用。我只是猜測這是對的,如果我錯了,那麼糾正我。

我還讀到onStop在低內存情況下不會調用 - 那麼該怎麼辦?

回答

2

如果在活動不可見時mediaPlayer預期停止,則需要onStop()例程。否則,mediaPlayer繼續播放。在較老的操作系統,薑餅和更早的版本中,活動可以執行onPause()--例如,當電話到達時 - 並且在極端情況下會被銷燬而沒有執行onStop()。我不知道一個正在運行的mediaPlayer會發生什麼。但是,如果有電話打進來,可能會停止onPause()中的mediaPlayer!在銷燬活動之前,以後的操作系統總是通過onStop()。在mediaPlayer上停止播放onPause()onStop()後調用mp.release()是正確的。

還需要刪除在mediaPlayers中持有的播放器的引用,這在上面的onStop()中不會發生。喜歡的東西:

@Override public void onCompletion(MediaPlayer mp) { 
     mp.stop(); // It's always safe to call stop() 
     mp.release(); // release resources internal to the MediaPlayer 
     mediaPlayers.remove(mp); // remove reference to MediaPlayer to allow GC 
    } 

然後

@Override public void onPause() { 
    for (Object mediaPlayer : mediaPlayers.toArray()) { 
      onCompletion((MediaPlayer) mediaPlayer); // stop, release, and free for GC, each mp. 
    } 
    super.onPause(); 
} 

(!我本來在上面的代碼for (Object mediaPlayer : mediaPlayers) {}但omfeddf345mnof32nisd45fgoq2t指出,我將修改一組在遍歷它感謝校正)

+0

所以我想'onPause'是最安全的選擇,你上面貼的代碼應該是足以適用於所有操作系統,包括新舊操作系統?只是想確認除了您上面發佈的代碼以外沒有額外的東西需要額外處理...... –

+0

我不認爲有任何額外需要,這就是我如何編程它。如果您的應用程序啓用了旋轉功能,那麼您的活動將被銷燬,其中包括對循環事件執行'onPause',然後重新創建,並且您必須在'onPause'中注意並且不要在'onCompletion'中調用onCompletion這種情況下,如果你想保持音頻去。最簡單的禁止旋轉!祝你好運! – emrys57

+0

感謝您的明確答覆。 –

0

只保留被調用的回調函數是onPause(),所以在某些情況下你可能會泄漏這個媒體播放器。如果停止播放器停止播放活動是不可接受的,你應該使用服務,並觀看某些事件(如來電等)