系统播放器 MediaPlayer
MediaPlayer 是 Android 中的一个多媒体播放类,我们可以通过它控制音视频流或本地音视频资源的播放过程。
状态图和生命周期
MediaPlayer 类主要的状态如下:
- Idle
- End
- Error
- Initialized
- Prepare
- Preparing
- Started
- Paused
- Stopped
- PlaybackCompleted
Media 的状态周期如下:

从图中可以看到 MediaPlayer 有以下一些状态。
Idle 和 End
MediaPlayer 创建示例或者调用 reset 函数后,播放器就被创建了,此时播放器处于 Idle(就绪)状态,调用 release 后就会变成 End(结束)状态,在这两种状态之间就是 MediaPlayer 的生命周期。
Error
在构造一个新 MediaPlayer,上层 APP 调用 getCurrentPosition、getVideoHeight、getDuration、getVideoWidth、setAudioStreamType(int)、setLooping(boolean)、setVolume(float, float)、pause、start、stop、seekTo(int)、prepare、prepareAsync 这些方法会出错。如果调用 reset 方法再调用它们,用户提供的回调方法 OnErrorListener.OnError,MediaPlayer 的状态会到 Error(错误)状态。所以,一旦不再使用 MediaPlayer,就需要调用 release 方法,以便 MediaPlayer 资源得到合理释放。
Initialized
当调用 setDataSource 方法时,MediaPlayer 状态会变成 Initialized(初始化)状态,如果 setDataSource 方法在非 Idle 状态时调用,会抛出 IllegalStateException 异常。
Prepared
MediaPlayer 有两种途径到达 Prepared 状态,一种是同步方式,另一种是异步方式。同步方式主要使用本地音视频文件,异步方式主要使用网络数据,需要缓冲数据。调用 prepare(同步方法)将传递 MediaPlayer 的 Initalized 的状态变为 Prepared 状态,或者调用 prepareAsync(异步方法)将传递的 MediaPlayer 的 Initialized 状态变为 Preparing 状态,最后到 Prepared 状态。注意,Preparing 是一个瞬时状态(时间比较短)。
Started
在 MediaPlayer 进入 Prepared 状态后,上层应用即可设置一些属性,如音视频的音量、screenOnWhilePlaying、looping 等。在播放控制开始之前,必须调用 start 方法并成功返回,MediaPlayer 的状态开始由 Prepared 转为 Started。当处于 Started 状态时,如果用户事先注册过 setOnBufferingUpdateListener,播放器内部会开始回调 OnBufferingUpdateListener.OnBufferingUpdate,这个回调方法主要使应用程序保持跟踪音视频流的 buffering(缓冲)status,如果 MediaPlayer 处于 Started 状态,再调用 start 方法是没有任何作用的。
Paused
MediaPlayer 在播放控制时可以是 Paused(暂停)和 Stopped(停止)状态的,且当前的播放进度可以被调整,当调用 MediaPlayer.pause 方法时,MediaPlayer 开始由 Started 状态变成 Paused 状态,这个过程是瞬间的,反之,在播放器内部是异步过程的。在状态更新并调用 isPlaying 方法前,将有一些耗时。已经缓冲过的数据流也要耗费数秒。
当 Start 函数从 Paused 状态恢复过来时,playback 恢复之前暂停的位置,接着开始播放,这时 MediaPlayer 的 Paused 状态又变成 Started 状态。如果 MediaPlayer 已经处于 Paused 状态,这时再调用 pause 方法是没有任何作用的,将保持 Paused 状态。
Stopped
当调用 stop 方法时,MediaPlayer 无论处于 Started、Paused、Prepared 或 PlaybackCompleted 中的哪一种状态,都将进入 Stopped 状态。一旦处于 Stopped 状态,playback 将不能开始,直到重新调用 prepare 或 prepareAsync 方法,且处于 Prepared 状态时才可以开始。
如果 MediaPlayer 已经处于 Stopped 状态了,这时再调用 stop 方法是没有任何作用的,将保持 Stopped 状态。
在 seek 操作完成后,如果事先在 MediaPlayer 注册了 setOnSeekCompleteListener,播放器内部将回调 OnSeekComplete.onSeekComplete 方法。当然 seekTo 方法也可以在其它状态下被调用,如 Prepared、Paused 及 PlaybackCompleted 状态。
PlaybackCompleted
当前播放位置可以通过 getCurrentPosition 方法获取,通过 getCurrentPosition 方法可以跟踪播放器的播放进度。当 MediaPlayer 播放到数据流的末尾时,一次播放完成,在 MediaPlayer 中事先调用 setLooping(boolean)并设置为 true,表示循环播放。MediaPlayer 依然处于 Started 状态。如果用 setLooping(boolean) 并设置为 false(不循环播放),播放器内部将回调 onCompletion.onCompletion 方法,这就表明 MediaPlayer 开始进入 PlaybackCompleted(播放完成)状态。当处于 PlaybackCompleted 状态时,调用 start 方法,将重启播放器从头开始播放数据。

浙公网安备 33010602011771号