在release()&之后避免来自MediaPlayer的IllegalStateException。重启()

时间:2014-08-24 23:58:03

标签: android android-mediaplayer android-lifecycle illegalstateexception

我有一个相当基本的活动+偏好Android应用,它使用MediaPlayer

简而言之,应用程序以MainActivity膨胀开始,当用户触摸某个按钮时,MediaPlayer会从initializeMediaPlayer()初始化(第一次使用new reset之后,然后是setDisplaysetDataSourcepreparesetLooping)。初始化Media Player并满足其他一些条件后,我调用一个基本上调用mMediaPlayer.start()的triggerAlarm方法。再次触摸上面的按钮时,我会拨打mMediaPlayer.stop()

onDestroy()内,我调用了mMediaPlayer.release(),这使我的MediaPlayer实例处于结束状态。我的问题是,一旦我这样做,我就无法再次使用MediaPlayer - 当我再次启动应用程序时,mMediaPlayer仍然处于End状态,所以我不能reset()它;我尝试使用mMediaPlayer = new MediaPlayer()代替reset(),但这也不起作用(我认为应用程序将对象引用混淆了,因为我可以启动媒体播放,但不能阻止它)。在这一点上,我无法想象是否有任何解决方案,笨拙或不可行(除了不release() MediaPlayer之外,但这对我来说是一个坏主意,即使是真的我需要播放的短小原始资源文件。)

编辑:相关代码和logcat

// All of this happens in MainActivity
private MediaPlayer mMediaPlayer;
@Override
protected void onDestroy()
{
    if ( mMediaPlayer != null && mMediaPlayer.isPlaying() )
        mMediaPlayer.stop();
    mMediaPlayer.release();
    super.onDestroy();
}

// Called on button click if the device is "unlocked"
private void deviceLock()
{
    // Code to register this activity as listener for sensor changes
    initializeMediaPlayer();
}

// Called on button click if the device is "locked"
private void deviceUnlock()
{
    // Code to unregister this activity as listener for sensor changes
    if ( mMediaPlayer.isPlaying() )
        mMediaPlayer.stop();
}

private void initializeMediaPlayer()
{
    if ( mMediaPlayer == null )
        mMediaPlayer = new MediaPlayer();
    else
    {
        // This is where I tried to have a try-catch block in which I would try to
        // call reset(), and if that threw an IllegalStateException I would
        // do mMediaPlayer = new MediaPlayer();
        mMediaPlayer = new MediaPlayer();
    }

    /** setDisplay() */

    /** setDataSource() */

    /** prepare() */

    /** Catch exceptions */
}

public void onSensorChanged( SensorEvent event )
{
    // If certain conditions are met, call triggerAlarm()
    triggerAlarm();
}

private void triggerAlarm()
{
    try
    {
        if ( !mMediaPlayer.isPlaying() )
            mMediaPlayer.start();
    }
    catch (IllegalStateException ise)
    {
        /** Should never happen because triggerAlarm() can only be called after deviceLock()
         * and deviceLock already initializes the media player, but still... */
        initializeMediaPlayer();
    }
}

所以为了得到崩溃,我会

  • 启动应用
  • 点击按钮调用deviceLock(),即运行new MediaPlayer()(如果这是第一次运行)或调用reset()(如果不是)。无论哪种方式,mMediaPlayer都应处于空闲状态。
    • 一旦mMediaPlayer空闲,其余的初始化就会顺利进行。
  • 可选择再次按下锁定/解锁按钮以运行deviceUnlock()。没有区别。
  • 点击后退按钮关闭应用程序。 onDestroy()被调用,mMediaPlayerrelease()编辑
  • 再次启动应用,然后再次浏览deviceLock()
  • 我们在initializeMediaPlayer()崩溃了。 mMediaPlayer不为null(它处于End状态,不是垃圾回收),因此我不会为它创建new MediaPlayer()。但随后reset()会抛出IllegalStateException,因为我试图在结束状态的MediaPlayer上调用它。如果我在捕获此异常时尝试强制该应用执行mMediaPlayer = new MediaPlayer(),则会遇到问题,一旦我在其上调用MediaPlayer,我就无法停止start()

0 个答案:

没有答案