本文将贯穿android的整个体系,深入剖析MediaPlayer的notify监听机制的前世今生。
本文主要阐述内容介绍:
一.java应用层上Listener监听机制的使用方式
二.java框架层中MediaPlayer类的notify机制的分析
三.jni层中java和c++代码中notify机制如何交互
四.c++层的MediaPlayer类中notify机制的分析
五.服务端MediaPlayerService中notify机制的分析
六.具体子服务MediaPlayer的notify机制的分析
七.子服务MediaPlayer的实例Nuplayer中notify机制的分析
一.java应用层上Listener监听机制的使用方式
关于如何使用MediaPlayer,可以参考android 的sdk文档,写的很详细。
这里简要介绍一下它怎么创建使用。
第一种方法,使用MediaPlayer.create()这个静态方法来创建,然后哦启动它。
MediaPlayer mp = MediaPlayer.create(context, R.raw.sound_file_1);
mp.start();
第二种方法,是new一个MediaPlayer的对象,通过setDataSource来设置播放的内容,接着调用prepare方法对真正的打开数据源准备播放。
MediaPlayer mp = new MediaPlayer();
mp.setDataSource(PATH_TO_FILE);
mp.prepare();
mp.start();
使用上面的两种方法创建好MediaPlayer,接着就是通过start方法来启动对媒体的播放。
我们先来看一下MediaPlayer的状态图
从状态图可以看出在创建到播放的过程中可能会出现各种状态和问题,比如,无法找到播放文件,播放数据错误,播放的准备进度等,在这种情况下,android为我们提供了一种事件的通知机制,来适时的给用户各种状态和错误的反馈。
android通过设置事件监听来对这些状态和错误来处理反馈。
比较常见的事件监听包括:
1.BufferingUpdate
public void setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener)
设置一个监听当播放网络的数据流的buffer发生变化的时候发出通知。
它的参数是一个接口
public interface OnBufferingUpdateListener
{
void onBufferingUpdate(MediaPlayer mp, int percent);
}
mp是调用这个接口的MediaPlayer对象,percent是数据缓存的百分比。
2.Completion
public void setOnCompletionListener (MediaPlayer.OnCompletionListener listener)
设置一个监听,当一个媒体是播放完毕的时候发出通知。
public interface OnCompletionListener
{
void onCompletion(MediaPlayer mp);
}
mp是调用这个接口的MediaPlayer对象
3.Error
public void setOnErrorListener (MediaPlayer.OnErrorListener listener)
设置一个监听,当使用异步操作出现错误时发送的通知。
使用prepare方法是启动同步方式,当prepare方法需要全部执行完后才能返回。
使用prepareAsync方法是启动异步方式,调用prepareAsync方法后直接返回,后台用在另一个线程中完成对prepare的准备工作。
这个error的错误监听的通知就是在异步的方式下才会发出的。
public interface OnErrorListener
{
boolean onError(MediaPlayer mp, int what, int extra);
}
mp是调用这个接口的MediaPlayer对象,what是错误的类型,extra是针对what错误的额外的代码
错误类型包括了:
MEDIA_ERROR_UNKNOWN:未指定的错误,一般没有使用。
MEDIA_ERROR_SERVER_DIED:媒体的后台服务挂了。
MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK:播放发生错误,或者视频本身有问题,例如视频的索引不在文件的开始部分。
返回true表示有错误发生,当返回false,或者没有调用这个监听时,将会调用OnCompletionListener。
4.Info
public void setOnInfoListener (MediaPlayer.OnInfoListener listener)
设置一个监听,当有信息或者警告的时候发出通知。
public interface OnInfoListener
{
boolean onInfo(MediaPlayer mp, int what, int extra);
}
mp是调用这个接口的MediaPlayer对象,what是消息的类型,extra是针对what消息的额外的代码
我们来看看都有哪些的消息
MEDIA_INFO_UNKNOWN:未指点消息,一般很少使用。从android源码中看,没人使用。
MEDIA_INFO_VIDEO_TRACK_LAGGING:从它的英文解释来看,我觉得是×××认为这个视频太负责了不能足够快速的解码出视频帧的时候发出的,当收到这个消息的时候我们可以让应用程序只播放音频而不去播放视频会更好点。这个是我个人观点。
MEDIA_INFO_BUFFERING_START:通知你要暂停一下播放,去进行一下buffer缓存,以便更好的播放。
MEDIA_INFO_BUFFERING_END:这条消息和上面那个MEDIA_INFO_BUFFERING_START上相对的,当buffer的缓存够的时候,通知你一下,你就可以接着去播放视频了。
MEDIA_INFO_METADATA_UPDATE:当有一组新的元数据有效的时候发出的通知。,什么是元数据啊,我不知道,以后知道了会更新。
MEDIA_INFO_BAD_INTERLEAVING:一个正常的媒体文件中,音频数据和视频数据因该是交错依次排列的,这样这个媒体才能被正常的播放,但是如果音频数据和视频数据没有正常交错排列,那里就会发出这个消息。
MEDIA_INFO_NOT_SEEKABLE:媒体不能被定位的时候发出的消息,这个时候可能这个媒体是在线流
5.Prepare
public void setOnPreparedListener (MediaPlayer.OnPreparedListener listener)
设置一个监听,当准备完成的时候发出通知
public interface OnPreparedListener
{