最近在维护公司的一个项目时,该项目是一个小游戏,玩过一局之后还可以再来一局,复用原来的Activity。在这个activity里实例化了5个MediaPlayer。测试部的同事发现,在玩的过程中会出现 突然就有几个声音源没有了声音,在玩过一局两局之后,这 种现象就非常明显。
刚开始知道这个BUG时,事实上,我对MediaPlayer的了解甚微,真不知如何下手去分析这样的一个问题。我先看了百度上的博客,对其进行了初步的了解,然后总感觉还是不够,于是又去翻官方的开发文档。发现了一个非常重要的图:
这个图说明了MediaPlayer的状态,讲述Mediaplayer的内部状态变化,根据代码,我事际上是没有发现有什么错误的迹象,因为它调用Reset==》setDataSource===>prepare===>start这个流程 没有任务错误。
幸好 MediaPlayer的开发提供了一个接口setOnErrorListener(android.media.MediaPlayer.OnErrorListener),这个接口可以监听到MediaPlayer错误时发出的信息,于是我把所有的Mediaplayer都加上这个接口,然后打出Log信息,果不其实,在游戏过程中,特别是完成一个关卡之后,这个接口更是被频繁地调用。
而且What=-38,extra=0,本以为拿着这个码去看官方文档就能够对症下药去分析问题了,结果却发现并不能,因为我没有找到这个-38的码的错误原因到底是什么?如果找到的朋友麻烦告知一声。
后来一想,假若是再来一局才会出现这个问题,那么应该可以从onPause或者onDestroy里发现一些问题,首先,还是发现了,原作者没有正确对mediaplayer进行释放,于是我进行release对象,但发现仍会出现该问题。
而我在onPause里发现,作者会在这里执行MediaPlayer的pause和stop操作,这个时候,我联想到上边的图,内心假设,假如此刻MediaPlayer并没有在播放,其实没有必要执行其pause和stop操作,于是我在其调用该方法前进行了一个判断,通过isPlaying方法,对操作进行过滤,然后将所有的这些操作都加上这种操作。在start的时候也加上了prepare方法(待验证),然后运行了程序,果然不再打出错误信息了。
这里还是提供这样的一个想法供参考吧,网上关于这个问题的解释实在太少啦。
补充一点:
如果你没有实现onErrorListener的onError方法,并且没有return true,那么根据源码,如果发生错误的话,回直接调用你的oncomPletion.onCompletion方法。源码如下:
加油,共勉~