如何有效地处理媒体播放器



此代码在我已经测试的设备上工作(所有MDPI级设备)。

private void stopSounds() {
    if (mp!=null && mp.isPlaying()) {
        mp.stop();
        mp.reset();
        mp.release();
        mp = null;
    }
}
private void playSounds(int sound) {
    stopSounds();
    mp = new MediaPlayer();
    mp = MediaPlayer.create(this, sound);
    mp.start();
    }
@Override
public void onClick(View v) {
    switch (v.getId()) {
    case R.id.button1:
        playSounds(R.raw.correct_amazing);
        break;
    case R.id.button2:
        playSounds(R.raw.correct_awesome);
        break;
    case R.id.button3:
        playSounds(R.raw.correct_chick);
        break;
    default:
        break;
    }
}

到目前为止尚无错误或例外,我考虑了释放媒体播放器对象(MP)完成(播放)。

所以我只是尝试添加oncompletionlistener,如下所示,在playsounds():

    private void playSounds(int sound) {
    stopSounds();
    mp = new MediaPlayer();
    mp = MediaPlayer.create(this, sound);
    mp.start();
    mp.setOnCompletionListener(new OnCompletionListener() {
        @Override
        public void onCompletion(MediaPlayer mep) {
            mep.stop();
            mep.reset();
            mep.release();
            mep = null;
        }
    });
}

然后开始抛出" iLlegalstateException",如下所示,

  01-22 17:51:24.150: W/dalvikvm(3081): threadid=1: thread exiting with uncaught exception (group=0x41e2e498)
  01-22 17:51:24.150: E/test(3081): Exception
  01-22 17:51:24.180: E/AndroidRuntime(3081): FATAL EXCEPTION: main
  01-22 17:51:24.180: E/AndroidRuntime(3081): java.lang.IllegalStateException
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at android.media.MediaPlayer.isPlaying(Native Method)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at com.Test.mediaplayertert.MPActivity.stopSounds(MPActivity.java:30)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at com.Test.mediaplayertert.MPActivity.playSounds(MPActivity.java:39)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at com.Test.mediaplayertert.MPActivity.onClick(MPActivity.java:61)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at android.view.View.performClick(View.java:4106)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at android.view.View$PerformClick.run(View.java:17150)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at android.os.Handler.handleCallback(Handler.java:615)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at android.os.Handler.dispatchMessage(Handler.java:92)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at android.os.Looper.loop(Looper.java:137)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at android.app.ActivityThread.main(ActivityThread.java:4793)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at java.lang.reflect.Method.invokeNative(Native Method)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at java.lang.reflect.Method.invoke(Method.java:511)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:808)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:575)
  01-22 17:51:24.180: E/AndroidRuntime(3081):   at dalvik.system.NativeStart.main(Native Method)

我的问题是,我在屏幕上有大约6个按钮,只要它们在活动中,用户就会按下它们,并且我需要分别播放"正确的"声音,"错误"声音。因此,它将需要连续按下。

通过setOnCompletionListener()。

释放MP对象后,我上述错误正在发生

我想知道如何在上述条件下有效地处理MediaPlayer(或)如何在完成播放后如何释放MediaPlayer对象?

当您在oncompletionlistener中停止以前的声音后单击按钮时,您的异常会发生。这是一个微妙的错误,很容易错过。这是发生的事情:

  1. 您单击一个按钮,然后调用playsounds(),在其中启动了全局媒体播放器对象,并设置了一个oncompletionlistener。

  2. 在OnCompletionListener()您尝试释放发射onCompletion

  3. 的播放器
  4. 现在,java是 by-value 。这意味着这里:

    @Override
    public void onCompletion(MediaPlayer mep)
    

    MEP是对您的全局MP对象的引用,因此您可以进行操作,例如stop(),reset()等,但是当您这样做时:

    mep = null;
    

    您是null'nig的 - 据我了解 - 该引用(这是一个值),而不是全局对象。

  5. 因此,假设声音完成(oncompletionListener被调用),然后单击另一个按钮,playsounds()被调用,wess notsounds()正在检查:

    if (mp != null ...  <-------- here, mp will NOT be null
    

    ,在同一条线上,您正在检查

    mp.isPlaying()) { <----------- THIS IS CAUSING AN EXCEPTION
    

    为什么?请记住,在OnCompletionListener中,您称为reset()和Release(),将MediaPlayer的状态分别置于闲置状态和最终状态,并且正如文档所说,如果在wrong状态中调用ISPlaying(),则将抛出一个例外:

    IllegalStateException-如果尚未初始化或已发布内部播放器引擎

解决方案:

稍微修改您的oncompletionListener,以使您的全局媒体播放器对象:

@Override
public void onCompletion(MediaPlayer mep) {
    mep.stop();
    mep.reset();
    mep.release();
    //null the global MediaPlayer object
    mp = null;
}

这里有一些关于爪哇通过的出色文章,它的解释比我的尝试要好得多:)

是java"通过参考"。或"通过价值"&quot?
http://javadude.com/articles/passbyvalue.htm

这些音频文件有多长时间?您是否考虑过使用Soundpool代替Mediaplayer?这里有一些很好的信息:

http://developer.samsung.com/android/technical-docs/playing-audio-andio-and-video-in-indroid

最新更新