2014-05-02 129 views
1

經過兩週的嘗試解決與我的媒體播放器代碼問題繼續有用戶報告崩潰,我在我的智慧結束試圖看看我做錯了什麼。Android媒體播放器不斷崩潰

媒體播放器和背景聲音對象初始化主類:

public class GameOver extends Activity{ 

public AdView adView; 
BackgroundSound mBackgroundSound; 
MediaPlayer mMediaPlayer; 

這裏是我的媒體播放器的代碼和與之相關聯的方法,我不叫上帶回點什麼壓:

public class BackgroundSound extends AsyncTask<Void, Void, Void> { 

    protected void onPreExecute() { 
     mMediaPlayer = MediaPlayer.create(GameOver.this, R.raw.welldone); 
    } 

    protected Void doInBackground(Void... params) { 
     mMediaPlayer.setVolume(100, 100); 
     mMediaPlayer.start(); 
     mMediaPlayer.setLooping(true); // Set looping 
     return null; 
    } 

    protected void onCancelled(Void v) { 
     try { 
      mMediaPlayer.stop(); 
      mMediaPlayer.reset(); 
      mMediaPlayer.release(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

} 

public void onPause() { 
    super.onPause(); 
    mBackgroundSound.onCancelled((Void) null); 
} 

public void onResume() { 
    super.onResume(); 
    mBackgroundSound = new BackgroundSound(); 
    mBackgroundSound.execute((Void) null); 

} 

以下是一些示例性崩潰:

java.lang.RuntimeException: An error occured while executing doInBackground() 
at android.os.AsyncTask$3.done(AsyncTask.java:200) 
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:274) 
at java.util.concurrent.FutureTask.setException(FutureTask.java:125) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:308) 
at java.util.concurrent.FutureTask.run(FutureTask.java:138) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1088) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:581) 
at java.lang.Thread.run(Thread.java:1019) 
Caused by: java.lang.IllegalStateException 
at android.media.MediaPlayer.setVolume(Native Method) 
at com.deucalion0.findtheanimal.Menu$BackgroundSound.doInBackground(Menu.java:235) 
at com.deucalion0.findtheanimal.Menu$BackgroundSound.doInBackground(Menu.java:1) 
at android.os.AsyncTask$2.call(AsyncTask.java:185) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:306) 
... 4 more 

而另一個:

java.lang.RuntimeException: An error occured while executing doInBackground() 
at android.os.AsyncTask$3.done(AsyncTask.java:299) 
at java.util.concurrent.FutureTask$Sync.innerSetException(FutureTask.java:273) 
at java.util.concurrent.FutureTask.setException(FutureTask.java:124) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:307) 
at java.util.concurrent.FutureTask.run(FutureTask.java:137) 
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:230) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1076) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:569) 
at java.lang.Thread.run(Thread.java:856) 
Caused by: java.lang.IllegalStateException 
at android.media.MediaPlayer.setLooping(Native Method) 
at com.deucalion0.findtheanimal.Menu$BackgroundSound.doInBackground(Menu.java:234) 
at com.deucalion0.findtheanimal.Menu$BackgroundSound.doInBackground(Menu.java:1) 
at android.os.AsyncTask$2.call(AsyncTask.java:287) 
at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:305) 
... 5 more 

我看了很多問題#1,試圖讓谷歌文檔的感覺,一切我都試過似乎是一個不好解決。我不知道如何着手,可有人請指教?

回答

2

你爲什麼用這種方式使用AsyncTask?

現在能做什麼:

  • 創建的MediaPlayer在主線程 - 這是一個漫長的過程,所以它應該去後臺線程,它可能會導致ANR次數。
  • 從後臺線程調用setVolume,start,setLooping - 這些都是非常短的命令,所以不需要在後臺運行它們。
  • 調用停止,重置並從主線程釋放。

這將是一個工作的解決方案:

  • 創建從後臺線程你的MediaPlayer。
  • 創建後,設置循環並開始播放。 (這些都是快速撥打的電話,所以如果您願意,也可以在主線程中使用,但只能在創建MediaPlayer後使用。)
  • 當您想停止播放時(在您的示例中,當調用onPause時),您可以調用stop()和release()。但是,如果它已經創建並開始(因爲它是在後臺線程中完成的,可能會在mediaplayer開始播放音頻之前暫停您的活動)之前進行檢查。

編輯:這是我測試的源代碼,它爲我工作(即使媒體播放器的準備時間實在是太慢了,它加載之前,活動暫停):

private MediaPlayer mMediaPlayer; 
private volatile boolean mMediaPlayerStopped ; 

@Override 
protected void onPause() { 
    Log.v("MusicTest", "Paused activity") ; 
    stopMediaPlayer(); 
    super.onPause(); 
} 

private void stopMediaPlayer() { 
    Log.v("MusicTest", "Stopping MediaPlayer") ; 
    mMediaPlayerStopped = true ; 
    if (mMediaPlayer != null) { 
     mMediaPlayer.stop() ; 
     mMediaPlayer.reset() ; 
     mMediaPlayer.release() ; 
     mMediaPlayer = null ; 
    } 
} 

private void startMediaPlayer() { 
    mMediaPlayerStopped = false ; 
    new AsyncTask<Void, Void, Void>() { 

     @Override 
     protected Void doInBackground(Void... params) { 
      Log.v("MusicTest", "Creating MediaPlayer") ; 
      MediaPlayer mediaPlayer = MediaPlayer.create(MainActivity.this, R.raw.alarm10); 
      mediaPlayer.setVolume(100, 100) ; 
      mediaPlayer.setLooping(true) ; 
      Log.v("MusicTest", "Starting MediaPlayer") ; 
      mediaPlayer.start() ; 
      mMediaPlayer = mediaPlayer ; 
      if (mMediaPlayerStopped) { 
       Log.v("MusicTest", "MediaPlayer was stopped while preparing") ; 
       stopMediaPlayer(); 
      } 
      return null; 
     } 
    }.execute(); 
} 

@Override 
protected void onResume() { 
    Log.v("MusicTest", "Resumed activity") ; 
    startMediaPlayer(); 
    super.onResume(); 
} 
+0

謝謝你的建議我會試試這個,但是在這個問題上花了幾個星期,當我現在看代碼的時候,我的腦海裏一片空白。如果你有時間可以在某些時候向你展示你的意思,這將是一個很大的幫助。再次感謝你的回答,這給了我一些更好的線索,知道發生了什麼。 – deucalion0

+2

我添加了一些示例源代碼。 – hunyadym