我的代码如下:
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();
}
但是此代码不起作用,我无法捕获任何异常,并且该错误仍显示在日志目录中。
答案 0 :(得分:1)
如果您打算随后立即致电prepare
,则应使用prepareAsync
而不是start
。之所以会得到IllegalStateException
,是因为它在您调用start
时可能不同步,因为它是异步准备的,尚未完成交易。
根据prepareAsync:
准备播放器异步播放。设置后 数据源和显示表面,您需要调用prepare() 或prepareAsync()。对于流,您应该调用prepareAsync(), 立即返回,而不是阻塞直到有足够的数据 缓冲。
还有prepare:
同步准备播放器进行播放。设置后 数据源和显示表面,您需要调用prepare() 或prepareAsync()。对于文件,可以调用prepare(),这会阻止 直到MediaPlayer准备播放为止。
同样,prepare
允许您立即调用start
,因为它同步运行。但是,可能还有其他情况可能引发IllegalStateException
,请参阅其valid and invalid states。
答案 1 :(得分:0)
我一直在努力找出问题所在。我发现活动停止后没有释放媒体播放器。由于媒体播放器仍位于内存中,因此在我重新启动活动的确切次数后,无法加载新的媒体播放器。在另一项活动中,我使用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