无法捕获 MediaPlayer 的 IllegalStateException
Not able to catch the IllegalStateException of MediaPlayer
我的代码如下所示:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource( "http://.../abc.mp3" );
mp.setOnPreparedListener( ... mp.start(); ... );
mp.prepareAsync();
真正的代码在开始之前检查了mp
是否准备好了。大多数情况下它工作正常。但有时(如果是弱连接)它仍然会遇到这个错误:
MediaPlayer: Error (-38,0)
MediaPlayerNative: start called in state 0, mPlayer(0x7424863b40)
所以,我决定抓住它:
try {
mp.start();
} catch (IllegalStateException e) {
Toast.makeText(...).show();
} catch (Throwable e) {
Toast.makeText(...).show();
}
但是这段代码不起作用,我无法捕获任何异常,并且该错误仍然显示在日志 cat 中。
如果您打算随后立即调用 start
,则应使用 prepare
而不是 prepareAsync
。你得到 IllegalStateException
是因为当你调用 start
时它可能不同步,因为它异步准备并且尚未完成事务。
根据prepareAsync:
Prepares the player for playback, asynchronously. After setting the
datasource and the display surface, you need to either call prepare()
or prepareAsync(). For streams, you should call prepareAsync(), which
returns immediately, rather than blocking until enough data has been
buffered.
和prepare:
Prepares the player for playback, synchronously. After setting the
datasource and the display surface, you need to either call prepare()
or prepareAsync(). For files, it is OK to call prepare(), which blocks
until MediaPlayer is ready for playback.
同样,prepare
允许您立即调用 start
,因为它是同步运行的。不过可能还有其他情况可以抛出IllegalStateException
,请参考其valid and invalid states.
我努力找出问题所在。而且我发现当 activity 停止时我没有释放媒体播放器。因为媒体播放器仍然位于内存中,所以在我重新启动 activity 的确切次数后,新的媒体播放器无法加载。在另一个 activity 中,我使用 SoundPool,它也无法加载更多流。
@Override
protected void onStop() {
super.onStop();
for (int i = 0; i < mediaPlayerMap.size(); i++) {
int key = mediaPlayerMap.keyAt(i);
MediaPlayer mp = mediaPlayerMap.get(key);
if (mp != null) {
mp.release();
mp = null;
}
}
}
Logcat:
E/AudioFlinger: no more track names available
E/AudioFlinger: createTrack_l() initCheck failed -12; no control block?
E/AudioTrack: AudioFlinger could not create track, status: -12
E/SoundPool: Error creating AudioTrack
参考文献:
SoundPool error: no more track names available
https://groups.google.com/forum/#!msg/android-platform/tyITQ09vV3s/jwNdyI2-7iYJ
我的代码如下所示:
MediaPlayer mp = new MediaPlayer();
mp.setDataSource( "http://.../abc.mp3" );
mp.setOnPreparedListener( ... mp.start(); ... );
mp.prepareAsync();
真正的代码在开始之前检查了mp
是否准备好了。大多数情况下它工作正常。但有时(如果是弱连接)它仍然会遇到这个错误:
MediaPlayer: Error (-38,0)
MediaPlayerNative: start called in state 0, mPlayer(0x7424863b40)
所以,我决定抓住它:
try {
mp.start();
} catch (IllegalStateException e) {
Toast.makeText(...).show();
} catch (Throwable e) {
Toast.makeText(...).show();
}
但是这段代码不起作用,我无法捕获任何异常,并且该错误仍然显示在日志 cat 中。
如果您打算随后立即调用 start
,则应使用 prepare
而不是 prepareAsync
。你得到 IllegalStateException
是因为当你调用 start
时它可能不同步,因为它异步准备并且尚未完成事务。
根据prepareAsync:
Prepares the player for playback, asynchronously. After setting the datasource and the display surface, you need to either call prepare() or prepareAsync(). For streams, you should call prepareAsync(), which returns immediately, rather than blocking until enough data has been buffered.
和prepare:
Prepares the player for playback, synchronously. After setting the datasource and the display surface, you need to either call prepare() or prepareAsync(). For files, it is OK to call prepare(), which blocks until MediaPlayer is ready for playback.
同样,prepare
允许您立即调用 start
,因为它是同步运行的。不过可能还有其他情况可以抛出IllegalStateException
,请参考其valid and invalid states.
我努力找出问题所在。而且我发现当 activity 停止时我没有释放媒体播放器。因为媒体播放器仍然位于内存中,所以在我重新启动 activity 的确切次数后,新的媒体播放器无法加载。在另一个 activity 中,我使用 SoundPool,它也无法加载更多流。
@Override
protected void onStop() {
super.onStop();
for (int i = 0; i < mediaPlayerMap.size(); i++) {
int key = mediaPlayerMap.keyAt(i);
MediaPlayer mp = mediaPlayerMap.get(key);
if (mp != null) {
mp.release();
mp = null;
}
}
}
Logcat:
E/AudioFlinger: no more track names available
E/AudioFlinger: createTrack_l() initCheck failed -12; no control block?
E/AudioTrack: AudioFlinger could not create track, status: -12
E/SoundPool: Error creating AudioTrack
参考文献:
SoundPool error: no more track names available
https://groups.google.com/forum/#!msg/android-platform/tyITQ09vV3s/jwNdyI2-7iYJ