在尝试修复媒体播放器代码问题两周后,仍然继续有用户报告崩溃,我不知所措,试图看看我在做什么错。

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

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


我已经阅读了许多Stackoverflow问题,试图理解Google文档,而我尝试过的一切似乎都是一个糟糕的解决方案。我不知道该如何进行,有人可以请教吗?

最佳答案

您为什么以这种方式使用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();
}

关于android - Android Media Player不断崩溃,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/23425428/

10-11 22:23
查看更多