android中MediaPlayer的生命周期

一、生命状态图

 

上图显示了MediaPlayer的生命周期和状态,单箭头的弧表示同步方法的调用,双箭头表示异步方法的调用。

二、生命周期详解

1、Idle状态

当MediaPlayer对象使用new创建了一个实例或者调用了reset()方法时,就进入了Idle状态。

2、End状态

在进入Idle状态后调用release()方法,就会变成End状态

在Idle和End状态之间是MediaPlayer的生命周期

3、Error状态

   在新创建一个Mediaplayer和在调用reset()方法后有一个不易察觉但非常重要的不同,即在这两种处于Idle状态下调用如下方法getCurrentPosition(),getDuration(),getVideoHeight(),getVideoWidth(),setAudioAttributes(AudioAttributes),setLooping(boolean),setVolume(float, float),pause(),start(),stop(),seekTo(long, int),prepare(),prepareAsync()会出现编程错误。如果实在构建完MediaPlayer对象后立即调用这些方法,则不会调用OnErrorListener.onError()方法,MediaPlayer将扔处于Idle状态;如果是在reset()之后调用这些方法时,则会触发OnErrorListener.onError()方法,MediaPlayer将切换到Error状态。

 一般来说,一些播放控制操作可能会由于各种各样的原因失败,比如不支持的音视频格式,音视频分辨率过高,或者输入数据流超时。当需要找到播放器处于Error原因时,需要用户实现调用setOnErrorListener注册OnErrorListener,将会返回错误信息。为了重新使用MediaPlayer,需调用reset()方法,使MediaPlayer恢复到Idle状态。

在非法的状态下调用prepare(),prepareAsync()或者重载setDataSource()方法都会引起IllegalStateException

4、End状态

在不使用MediaPlayer时建议立即调用release()方法一遍MediaPlayer资源得到合理的释放。如果未能调用release()方法,可能会导致MediaPlayer对象初始化失败。在release()方法后MediaPlayer进入到End的状态,一旦MediaPlayer进入到End状态,他将不能再被使用,而且不能再回到MediaPLayer的其他状态。此时MediaPlayer的生命周期终止。

注意,使用new创建的MediaPlayer对象处于Idle状态,但是使用create方法创建的则不处于Idle的状态,如果使用create方法创建成功则直接处于Prepared状态

5、Initialized状态

当调用setDataSource(FileDescriptor)}, setDataSource(String), setDataSource(Context, Uri) ,setDataSource(FileDescriptor, long, long)或者setDataSource(MediaDataSource)任意一个方法时,将会使MediaPlayer的Idle状态变为Initialized状态。如果在非Idle状态下调用setDataSource方法,就会抛出IllegalStateException异常。所以当重载setDataSource方法时,需要抛出IllegalStateException和IOException异常。

6、Prepared状态

MediaPlayer只有在进入Prepared状态后才能开始播放.有两种方式可以使MediaPlayer进入Prepared状态:一种是调用同步方法prepared(),一旦该方法调用返回MediaPlayer对象就会进入Prepared状态。另一种是调用异步方法prepareAsync(),该方法调用返回后首先会将MediaPlayer对象转换成Preparing状态,同时内部播放器继续做其他的工作,直到准备工作完成。如果用户预先调用了setonPreparedListener注册了onPreparedListener函数,当准备工作完成后或者调用Prepared()返回后内部播放器将回调onPreparedListener中的onPrepared回调函数。

注意:Preparing是暂时状态,在非Initialized状态下调用prepared()或者prepareAsync()会抛出IllegalStateException异常。在Prepared状态下,音视频的volume、screenOnWhilePlaying、looping属性,可以通过调用相应的set方法进行调整。

7、Started状态

在播放控制开始之前,必须调用start()方法。当start()方法成功返回时,MediaPlayer的状态由Prepared状态转换成Started状态。可以通过调用isPlaying()方法判断是否处于Started状态。如果用户事先注册了setOnBufferingUpdateListener,播放器内部会回调OnBufferingUpdateListener.onBufferingUpdate()。这个回调主要是使应用程序保持跟踪音视频的buffering状态。

注意:如果MediaPlayer已经处于Started状态,再调用start()是没有任何作用的。

8、Paused状态

MediaPlayer可以暂停和停止播放,并且可以调整当前的播放位置。当调用pause()方法并且回调成功时,MediaPlayer进入Paused状态。需要注意的是:MediaPlayer从Started状态到Paused状态和从Paused状态到Started状态都是异步进行的,也就是说在调用isPlaying()查询状态时需要注意这一点。调用start()去恢复处于Paused状态的MediaPlayer时,当start函数成功返回时将从暂停的位置重新开始播放。MediaPlayer将由Paused变为Started状态。如果MediaPlayer处于Paused状态,再次调用pause()将没有任何作用。

9、Stopped状态

当MediaPlayer处于Started,Paused,Prepared或者PlaybackCompleted状态时,调用stopped()后,MediaPlayer将进入Stopped状态。一旦MediaPlayer处于Stopped状态,直到用户重新调用prepareAsync()或者prepared()且处于Prepared状态后,播放才能重新开始。如果MediaPlayer已经处于了Stopped状态,再调用stop()是没有任何作用的,将保持Stopped的状态。

10、PlaybackCompleted状态

当播放到数据流的末尾时,播放结束。如果setLooping(boolean)被设置为true,则循环播放,MediaPlayer依然处于Started状态。如果setLooping(boolean)被设置为false,如果用户提前注册了setOnCompletionListener监听,则会回调函数OnCompletion.onCompletion(),此时MediaPlayer会进入到PlaybackCompleted状态。当MediaPlayer处于PlaybackCompleted状态时,调用start()函数可以重新开始音视频的播放。

快进和后退

可以通过调用seekTo(long, int)方法,调整当前的播放位置。虽然异步方法seekTo(long, int)可以立即返回,但是调整播放时间的工作还是需要一些时间,特别是当音视频正在缓冲时。如果mediaPlayer实现注册了setOnSeekCompleteListener,在seek操作结束后播放器会回调OnSeekComplete.onSeekComplete()。需要注意的是seekTo(long, int)方法不仅可以在Started状态下调用还可以在Prepared,Paused或者PlaybackCompleted状态下调用。

除此之外可以通过getCurrentPosition()方法,获取当前的播放进度。

 

 

 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值