Android媒体播放器不断崩溃

Android媒体播放器不断崩溃,android,android-mediaplayer,Android,Android Mediaplayer,经过两周的努力,我的媒体播放器代码仍然存在问题,用户不断报告崩溃,我已经不知所措,试图看看我做错了什么 在主类中初始化的媒体播放器和背景声音对象: public class GameOver extends Activity{ public AdView adView; BackgroundSound mBackgroundSound; MediaPlayer mMediaPlayer; 这是我的媒体播放器代码和与之相关的方法,我不会在按下后调用任何内容: public class

经过两周的努力,我的媒体播放器代码仍然存在问题,用户不断报告崩溃,我已经不知所措,试图看看我做错了什么

在主类中初始化的媒体播放器和背景声音对象:

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: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

我读过很多关于Stackoverflow的问题,试图理解Google文档,我所尝试的一切似乎都是一个糟糕的解决方案。我不知道如何继续,请有人提出建议吗?

您为什么要以这种方式使用AsyncTask

它现在做的是:

  • 在主线程上创建MediaPlayer-这是一个很长的过程,因此它应该转到后台线程,这可能会导致ANR
  • 从后台线程调用setVolume、start、setLooping-这些命令非常短,因此无需在后台运行它们
  • 从主线程调用stop、reset和release
什么是可行的解决方案:

  • 从后台线程创建MediaPlayer
  • 创建后,设置循环并开始播放。(这些是快速调用,所以如果您愿意,可以从主线程执行,但只能在创建MediaPlayer后执行。)
  • 当您想停止播放时(在您的示例中,当调用onPause时),可以调用stop()和release()。但是,如果已经创建并启动了活动,请在之前进行检查(因为它是在后台线程中完成的,所以有可能在mediaplayer开始播放音频之前暂停活动)
编辑:这是我测试过的源代码,它对我很有效(即使媒体播放器的准备时间非常慢,并且活动在加载之前暂停):

私有媒体播放器层;
私有易失性布尔值,分层覆盖;
@凌驾
受保护的void onPause(){
Log.v(“音乐测试”,“暂停活动”);
stopMediaPlayer();
super.onPause();
}
私有媒体播放器(){
Log.v(“MusicTest”、“停止MediaPlayer”);
mmediplayerstopped=真;
if(mmediplayer!=null){
mmediplayer.stop();
mmediplayer.reset();
mmediplayer.release();
mmediplayer=null;
}
}
私有void startMediaPlayer(){
mmediplayerstopped=false;
新建异步任务(){
@凌驾
受保护的Void doInBackground(Void…参数){
Log.v(“MusicTest”,“创建MediaPlayer”);
MediaPlayer=MediaPlayer.create(MainActivity.this,R.raw.alarm10);
mediaPlayer.setVolume(100100);
mediaPlayer.setLooping(true);
Log.v(“MusicTest”,“启动MediaPlayer”);
mediaPlayer.start();
mMediaPlayer=mediaPlayer;
如果(层顶){
Log.v(“MusicTest”,“MediaPlayer在准备时被停止”);
stopMediaPlayer();
}
返回null;
}
}.execute();
}
@凌驾
受保护的void onResume(){
Log.v(“音乐测试”,“恢复活动”);
startMediaPlayer();
super.onResume();
}

为什么要以这种方式使用AsyncTask

它现在做的是:

  • 在主线程上创建MediaPlayer-这是一个很长的过程,因此它应该转到后台线程,这可能会导致ANR
  • 从后台线程调用setVolume、start、setLooping-这些命令非常短,因此无需在后台运行它们
  • 从主线程调用stop、reset和release
什么是可行的解决方案:

  • 从后台线程创建MediaPlayer
  • 创建后,设置循环并开始播放。(这些是快速调用,所以如果您愿意,可以从主线程执行,但只能在创建MediaPlayer后执行。)
  • 当您想停止播放时(在您的示例中,当调用onPause时),可以调用stop()和release()。但是,如果已经创建并启动了活动,请在之前进行检查(因为它是在后台线程中完成的,所以有可能在mediaplayer开始播放音频之前暂停活动)
编辑:这是我测试过的源代码,它对我很有效(即使媒体播放器的准备时间非常慢,并且活动在加载之前暂停):

私有媒体播放器层;
私有易失性布尔值,分层覆盖;
@凌驾
受保护的void onPause(){
Log.v(“音乐测试”,“暂停活动”);
stopMediaPlayer();
super.onPause();
}
私有媒体播放器(){
Log.v(“MusicTest”、“停止MediaPlayer”);
mmediplayerstopped=真;
if(mmediplayer!=null){
mmediplayer.stop();
mmediplayer.reset();
mmediplayer.release();
mmediplayer=null;
}
}
私有void startMediaPlayer(){
mmediplayerstopped=false;
新建异步任务(){
@凌驾
受保护的Void doInBackground(Void…参数){
Log.v(“MusicTest”,“创建MediaPlayer”);
MediaPlayer=MediaPlayer.create(MainActivity.this,R.raw.alarm10);
mediaPlayer.setVolume(100100);
mediaPlayer.setLooping(true);
Log.v(“MusicTest”,“启动MediaPlayer”);
mediaPlayer.start();
mMediaPlayer=mediaPlayer;
如果(层顶){
Log.v(“MusicTest”,“MediaPlayer在准备时被停止”);
stopMediaPlayer();
}
返回null;
}
}.execute();
}
@凌驾
受保护的void onResume(){
Log.v(“音乐测试”,“恢复活动”);
startMediaPlayer();
super.onResume();
}

谢谢你的建议,我会试试这个,但在这个问题上花了几周时间,当我现在看代码时,我的脑子一片空白。如果你有时间,你可以吗
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
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();
}