无法捕捉 MediaPlayer 的 IllegalStateException

Posted

技术标签:

【中文标题】无法捕捉 MediaPlayer 的 IllegalStateException【英文标题】:Not able to catch the IllegalStateException of MediaPlayer 【发布时间】:2018-11-21 09:06:29 【问题描述】:

我的代码如下所示:

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();

但是这段代码不起作用,我无法捕获任何异常,并且该错误仍然显示在 log cat 中。

【问题讨论】:

"并且那个错误仍然显示在 log cat 中" 异常是因为那个错误而被抛出的,而不是相反。所以你不会通过捕获异常来摆脱错误日志。 @Michael 但我仍然无法捕捉到那个错误 【参考方案1】:

如果您打算之后立即致电start,则应使用prepare 而不是prepareAsync。你得到IllegalStateException,因为当你调用start时它可能不同步,因为它异步准备并且还没有完成事务。

根据prepareAsync:

准备播放器进行异步播放。设置后 数据源和显示表面,您需要调用 prepare() 或准备异步()。对于流,你应该调用 prepareAsync(), which 立即返回,而不是阻塞直到有足够的数据 缓冲。

还有prepare:

准备播放器进行播放,同步。设置后 数据源和显示表面,您需要调用 prepare() 或准备异步()。对于文件,调用prepare()就可以了,它会阻塞 直到 MediaPlayer 准备好播放。

同样,prepare 允许您立即调用 start,因为它是同步运行的。不过可能还有其他情况可以抛出IllegalStateException,请参考其valid and invalid states。

【讨论】:

prepareprepareAsync 都试过了。他们大部分时间都工作得很好。但有时没有(很少)。我想处理这些案子 明白,prepare 然后start 应该可以正常工作,但也有其他情况可以抛出IllegalStateException,请参考developer.android.com/reference/android/media/… 并再次检查您的代码。 :) 谢谢。活动停止时我忘记释放媒体播放器。这个错误发生在我重新启动活动的确切次数之后【参考方案2】:

我努力找出问题所在。我发现当活动停止时我没有释放媒体播放器。因为媒体播放器仍然位于内存中,所以在我重新启动活动的确切次数后,新的媒体播放器无法加载。在我使用 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 的 IllegalStateException的主要内容,如果未能解决你的问题,请参考以下文章

无法在 Nexus 5 中同时播放两个 MediaPlayer

JavaFX:MediaPlayer 无法播放电影

Android MediaPlayer 无法设置数据源 uri

MediaPlayer无法在Android Things Raspberry Pi 3上运行

Android MediaPlayer 无法 SetDataSource()

无法使用 MediaPlayer 对象在 Android 中播放许多音频文件