2014-05-02 128 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