MediaPlayer在new出来之后或者调用了reset()方法之后就进入了Idle状态,直到调用release()方法进入End状态结束。
在new出来之后和调用reset()方法之间有一点微小的差别,如果MediaPlayer仅仅只是new出来而没有调用reset()方法,播放器内部的播放引擎和对象的状态都还没有改变,如果此时调用getCurrentPosition()、getDuration()、getVideoHeight()、getVideoHeigh()、setVideoStreamType(int)、setLooping(boolean)、setVolume(float,float)、pause()、start()、stop()、seekTo(int)、prepare()和prepareAsync()方法都无法返回,因为框架无法回调客户端程序注册的OnErrorListener.OnError()方法,调用reset()方法之后,调用这些方法的错误信息就将被OnError()方法捕捉并返回。
MediaPlayer对象一旦确定不再使用就应该立即调用release()方法,释放与MediaPlayer对象关联的资源,以免占有硬件资源。导致之后创建的MediaPlayer对象无法使用资源。
MediaPlayer方法可以调用多个重载的setDataSource()方法从idle状态进入initialized状态。如果调用setDataSource()方法的时候,MediaPlayer对象不是出于idle状态,会报出IllegalStateException异常。SetDataSource()方法在调用的时候可能会发生IllegalArgumentException和IOException。
如果MediaPlayer是调用的自己的重载方法Create()传入资源文件的,那么此时MediaPlayer没有进入initialized状态,而是直接进入了prepared状态。
MediaPlayer可以调用prepared()方法和preparedAsync()方法进入prepared状态。调用prepared()方法直接进入parpared状态,调用preparedAsync()方法会进入preparing状态并返回,内部的播放引擎会继续完成未完成的工作。这两个方法可能发生IllegalStateException异常。
进入prepared状态后,会自动调用客户端程序注册的OnPreparedListener.OnPrepared()方法,可以在此方法里对MediaPlayer对象进行播放,及各种数据的获得,以及调整音量或者屏幕尺寸等操作。
在prepared状态下就可以调用start()方法进行播放了,此时进入started()状态,处于此状态下再次调用start()方法则没有影响。此状态下也会自动调用客户端注册的OnBufferingUpdateListener.OnBufferingUpdate()回调方法,对流播放缓冲的状态进行追踪。
pause()方法和start()方法是对应的,调用pause()方法会进入paused状态,调用start()方法继续播放。
stop()方法会使处于started、paused、prepared、playbackCompleted状态的MediaPlayer对象进入stoped状态,播放停止。
seekTo()方法可以调整播放的位置。seekTo方法是异步执行的,所以它可以马上返回。但是对于流媒体的播放,可能seekTo()方法会需要几秒钟的时间去完成。当seekTo完成时,会调用客户端注册的OnSeekCompleteListener.OnSeekComplete()回调方法。可以在此方法里做一些播放屏幕上的更新变化,比如发送隐藏控制界面的消息。
当资源播放完毕时,如果调用了setLooping(boolean)方法,会自动进入started状态重新播放,如果没有调用则会自动调用客户端播放器注册的OnCompletionListener.OnCompletion()方法,此时MediaPlayer对象进入playbackCompleted状态,在此状态里可以调用start()方法重新进入started状态。
播放View是继承SurfaceView的自定义View,继承SurfaceView后可以注册surfaceHolder的callback回调接口,实现其surfaceCreated()、surfaceChanged()及surfaceDestoryed()方法,surfaceCreated()方法在自定义播放View被创建的时候调用,surfaceChanged()方法在其改变的时候调用,surfaceDestoryed()方法在其销毁的时候调用。SurfaceHolder的生命周期是MediaPlayer在播放音频和视频时候的最大区别。通过SurfaceHolder的三个生命周期函数可以创建和释放某些资源。
Android内置的播放器并不是可以播放所有格式的视频文件,不能播放时videoHeight=0,videoWidth=0,以此来判断是否播放视频。
有的视频尺寸和播放View不一致时,可以重写OnMeasure(int,int)方法去调整视频播放时候的尺寸,以适应整个屏幕。其中在重写OnMeasure(int,int)方法时需要注意必须调用setMeasuredDimension(int,int)方法。