Android多媒体学习之MediaPlayer生命周期介绍
本文主要介绍MediaPlayer介绍之状态图及生命周期,围绕以下两个部分进行介绍:
1,MediaPlayer状态图。
2,介绍MediaPlayer的各个状态
Android的MediaPlayer包含了Audio和video的播放功能,用于控制playback的视频/音频文件及流,在Android的界面上,Music和Video两个应用程序都是通过调用MediaPlayer来实现的。
MediaPlayer的状态图
Paste_Image.png
椭圆代表MediaPlayer的驻留状态。
箭头代表状态之间的转换过程,单箭头代表同步方法,双箭头代表异步方法。
状态介绍:
Idle状态
当MediaPlayer调用reset()方法或者通过new的方式创建新的MediaPlayer对象后,MediaPlayer此时处于Idle状态,也称闲置状态或者就绪状态。在 Idle 状态无法调用 getCurrentPosition(), getDuration(), getVideoHeight(), getVideoWidth(), setAudioStreamtype(int), setLooping(boolean), setVolume(float, float), pause(), start(), stop(), seekTo(), prepare(), prepareAsync() 方法都是错误的。
两种进入 Idle 状态方法的区别:
new MediaPlayer() 进入 Idle 状态 : 此时 MediaPlayer 内部引擎 和 状态都没有改变, 调用上面的方法之后, 将 无法调用 OnErrorListener.onError() 方法;
reset() 进入 Idle 状态 : 此时假设调用上面的方法, 内部的引擎就会回调 OnErrorListener.onError() 方法;
创建 和 重载 MediaPlayer 区别:
创建 MediaPlayer : 通过new MediaPlayer()创建的对象处于 Idle (闲置) 状态;
重载 MediaPlayer : 通过 create() 方法创建的 MediaPlayer 对象处于 Prepare (准备) 状态;
End状态
当MediaPlayer调用release()方法之后,MediaPlayer置为End状态,该方法会释放 播放引擎 中与 MediaPlayer 相关的资源,End 状态代表 MediaPlayer 生命周期结束,处于End状态下的MediaPlayer无法通过任何方法转化到生命周期中的其他状态,生命周期已经终止。
在Idle状态和End状态之间的状态就是MediaPlayer的生命周期。
Error状态
控制操作可能会由于各种各样的原因而失败,如不支持的音视频格式,分辨率过高,流超时等待。
在这种情况下,只要我们事先通过setOnErrorListener设置过onErrorListener监听,同时MediaPlayer内部通过onErrorListener.onError回调方法,将错误信息传递出去,通过这些信息找到发生错误的原因。一旦发生错误,MediaPlayer将会进入Error状态,我们可以通过reset方法将MediaPlayer重新置为Idle状态。
Initializized状态
MediaPlayer在 Idle 状态调用setDataSource()之后,状态置为Initializized状态,只能在Idle下调用setDataSource方法,否则会报出IllegalStateException 异常。另外,在重载setDataSource方法时,记得抛出IllegalArgumentException和IOException异常。
Prepared状态
两种情况:
在Initializized状态调用prepare()方法之后,如果成功返回,状态置为Prepared状态
在Preparing状态调用onPreparedListener.onPrepared()方法,状态置为Prepared状态
Preparing状态
在Initializized状态或者Stopped状态调用parepareAsync()方法,状态置为Preparing状态
在 Preparing 状态时, 播放器引擎会继续完成准备工作, 同步版本号返回或者 异步版本号准备工作完成就会调用 OnPrepareListener.onPrepared() 方法进入 Prepared 状态;Preparing状态只是一个瞬时状态。
Started状态
Paste_Image.png
在Prepared状态下调用start()方法,状态转换为Started状态状态
不论在什么状态下调用 isPlaying() 方法, 都能够推断 MediaPlayer 是否在 Started 状态;
在 Started 状态, MediaPlayer通过调用 OnBufferingUpdateListener.onBufferingUpdate() 方法,传递获取视频音频流的缓冲状态,所以用户可以通过setOnBufferingUpdateListener监听这些信息。如果MediaPlayer此时已经处于Started状态,调用start()方法将不会有任何作用。
Paused状态
Paste_Image.png
在Started状态调用pause()方法,状态将Paused状态。Started 状态转换为 Paused 状态需要一定的时间, 这个过程是异步的, 过一段时间之后 isPlaying() 状态才会改变;在Paused状态下调用start()方法,又会回到Started状态
Stop状态
Paste_Image.png
在 Prepared, Started, Paused, PlaybackCompleted 状态下 调用 stop() 方法, MediaPlayer 会置为Stopped 状态,一旦进入Stop状态,不能直接转移到Started状态,只能通过调用prepare()方法进入到Prepared状态,然后调用start()方法重新进入Started状态。
PlaybackCompleted状态
如果之前使用了 setLooping() 开启了循环模式, 播放完成之后 MediaPlayer 会又一次进入 Started 状态;如果没有设置循环模式, 那么播放完成之后会调用 OnCompletion.onCompletion() 回调方法, MediaPlayer 会进入 PlaybackCompleted 状态;用户可以调用 MediaPlayer.setOnCompletionListener() 注册该监听器,在 PlaybackCompleted 状态时, 调用 satrt() 方法能够进入 Started 状态;从而从头开始控制音视频源。
seekTo() 方法说明
当调用seekTo() 方法时,playback的位置可以被调整,这是一个异步方法,该方法被调用之后引擎会回调 OnSeekComplete.onSeekComplete()方法, 用户通过 setOnSeekCompleteListener() 方法注册去监听进度的变化,该方法能够在 Prepared, Paused, PlaybackCompleted 状态进行调用,调用 getCurrentPosition() 方法, 能够获取当前播放的位置, 能够帮助播放器更新进度条;