异步准备资源
使用Mediaplayer播放视频或者音频是非常有效的方式。然而想要完美的使用它来完成你的逻辑你必须要注意以下几点。例如,prepare()方法的执行可能需要耗费很长的时间(需要去获取媒体数据或者是编解码),因此开发者不能在UI线程中调用这个方法。如果在UI线程中调用了这个方法,那么很有可能给用户造成很不好的体验,甚至引发ANR错误。即使你预计你所有加载的资源不会超过10秒,但是仍然会造成卡顿,用户可以很明显的感受到,觉着这个程序怎么运行这么慢啊。
为了避免UI线程被阻塞,在其他线程中调用prepare方法,然后在方法执行完后通知主线程。Android sdk提供了一种非常简单的方式来解决这个问题,你可以使用prepareAsync()方法,这个方法在其他线程中执行prepare操作,一旦完成,立刻调用MediaPlayer.OnPreparedListener, 来通知主线程我已经准备完毕了,可以播放了。
管理好状态
另外一个开发者必须要多加小心的地方是Medplayer的状态管理。因为一些Medplayer的方法开发者必须在Mediaplayer合适的状态下调用,否则很有可能抛出异常或者未知的错误。
MediaPlayer的类文档详细的介绍了MediaPlayer的各种状态,某个方法的调用可以导致的MediaPlayer状态变化。例如,当开发者刚刚创建了MediaPlayer,那么这个时候再idle状态。在这个节点,你可以调用
setDataSource()方法来进行初始化,将MediaPlayer进入到Initialized状态。接着可以调用prepare() 或者 prepareAsync() 方法,当MediaPlayer完成了prepare操作,MediaPlayer进入到Prepared状态。这也就意味着你可以调用start()方法来播放媒体资源了。根据图表中的展示,这个时候MediaPlayer可以通过调用方法start(), pause(),seekTo()等等在Started,Paused和PlaybackCompleted状态之间进行切换了。当调用完了stop()方法,你就不能再调用start方法了,直到MediaPlayer重新prepare。
在写代码的时候,永远心里想着MediaPlayer的各种状态变化,因为大部分的bug都是在某个状态下调用了错误的方法导致的。
释放MediaPlayer
MediaPlayer占用非常多的宝贵的系统资源,所以你必须确保释放MediaPlayer资源,没有让他不必要的使用系统资源。当不需要MediaPlayer的时候,你必须调用release()方法来确保之前分配给MediaPlayer的资源被释放掉。例如你的Activity收到onStop回调了,你就很有必要来释放掉MediaPlayer了,除非你有特殊的需要。当重新回到前台或者重启了,你可以重新创建一个MediaPlayer,并且prepare他来重新播放了。
如何释放一个MediaPlayer?
mediaPlayer.release();
mediaPlayer = null;
举一个简单的例子,假设当你的Activity stop的时候,你没有释放MediaPlayer,而是在Activity start的时候,重新创建了一个新的。或者当用户横竖屏切换手机的时候(没有特殊处理,Activity会重新创建),如果多旋转几次的话,很快MediaPlayer就占用了系统绝大部分资源,造成运行缓慢,无响应等等。