我有一个相当基本的活动+偏好Android应用,它使用MediaPlayer
。
简而言之,应用程序以MainActivity
膨胀开始,当用户触摸某个按钮时,MediaPlayer会从initializeMediaPlayer()
初始化(第一次使用new
reset
之后,然后是setDisplay
,setDataSource
,prepare
和setLooping
)。初始化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都应处于空闲状态。
deviceUnlock()
。没有区别。onDestroy()
被调用,mMediaPlayer
被release()
编辑deviceLock()
。initializeMediaPlayer()
崩溃了。 mMediaPlayer
不为null(它处于End状态,不是垃圾回收),因此我不会为它创建new MediaPlayer()
。但随后reset()
会抛出IllegalStateException
,因为我试图在结束状态的MediaPlayer
上调用它。如果我在捕获此异常时尝试强制该应用执行mMediaPlayer = new MediaPlayer()
,则会遇到问题,一旦我在其上调用MediaPlayer
,我就无法停止start()
。