转载请把头部出处链接和尾部二维码一起转载,本文出自:http://blog.csdn.net/hejjunlin/article/details/52392430
前言:前一篇的mediaPlayer框架,对于各个模块的关系,得先从核心类MediaPlayer铺开,同样看下今天的Agenda:
今天分析的是从MediaPlayer创建到MediaPlayer调用setDataSource过程
以往总是把时序图放在最后总结,有些人觉得一上来没有个大概,无从下手,所以,先把时序图附上,一步一步对着时序图看看每个阶段经历的过程
MediaPlayer时序图一(create->setDataSource, 后面文章还有,暂且这么命名):
当外部调用MediaPlayer.create(this,”http://www.xxx.mp4“)时,进入我们MediaPlayer的创建过程:
以上代码可以总结为:当MediaPlayer通过Create方式创建播放器时,内部new出MediaPlayer对象 ,并setDataSource,并做好prepare的动作。这时外面只须调用下start方法,音视频资源将能播放起来。
通常我们用通过构造MediaPlayer,然后自己setDataSource,prepare等操作。无论哪种都要先经过new MediaPlayer(),我们看下构造中做了什么操作:
注意这里有个EventHandler,虽然今天不是重点要说的,我们可以先了解下它:
接下来看native层如何创建一个mediaplayer,在说native_up之前,我们注意,一般加载so都是在静态代码块中, 在MediaPlayer中有一段静态代码块,用于初始jni相关,早于构造方法,在加载类时就执行。一般是全局性的数据,变量,可以放在这。这里是加载media_jni.so文件。
开始进入android_media_MediaPlayer.cpp分析,第一个方法,就是在java静态代码块调入的native_init:
被native层调用,就是反向调用,仅被使用EventHandler post事件回到主线程中,很多用post开头,基本都是post到主线程,用软引用指向原生的MediaPlayer,以便native代码是安全的,当MediaPlayer可在native释放,调到java中的实现部分如下:
以上就是native_init方法,可以看到,就是做了一些准备工作,获取一些方法,一些要用的成员变量。接着回到之前说的,create中MediaPlayer构造函数,有一个native_setup,在android_media_MediaPlayer.cpp找到对应方法:
可以看到会设置一些回调用的listener及创建c++中的MediaPlayer对象。
上面就是MediaPlayer的构造过程:构造后接下来要设置数据源,进而到了setDataSource操作,我们看下setDataSource做了什么操作:
先看看如果送的setDataSource中的uri是文件类型:
开始进入jni层,发现找不到android_media_MediaPlayer_setDataSource方法,可以发现有一个方法名对应映射方法声明:
以上这个方法名字映射,如果看过JNIEnv * 源码的话,对上面这些并不陌生,无非也是映射,不影响我们分析,在这里我们接下来要去找android_media_MediaPlayer_setDataSourceFD这个函数看看:
接着看process_media_player_call方法:
以上代码总结为:当 mp->setDataSource(fd, offset, length)方法后得到status后,对各种状态进行notify。有异常的直接抛出,这样也就不会影响mediaplayer后面的执行过程。
接下来看下以http/rtsp传入到jni中,在java层对应的nativeSetDataSource方法:
在jni中通过映射表,可对应到android_media_MediaPlayer_setDataSourceAndHeaders:
到此,setDataSource的过程就完成了。这里要注意两个点,一个是从Java->jni->c++正向调用过程(前面从java到native都是正向过程),一种是c++ -> jni -> java层过程(如 mp->setDataSource( httpService, pathStr, headersVector.size() > 0? &headersVector : NULL),那有人肯定会问了?这样来回调的好处是什么?
接下来看下在setDataSource之后,开始进行mp.setDisplay(holder)
MediaPLayer.java -> setDisplay
对于2,同样在android_media_MediaPlayer.cpp找到其对应方法:
这里有几个概念要理解下:
第一时间获得博客更新提醒,以及更多android干货,源码分析,欢迎关注我的微信公众号,扫一扫下方二维码或者长按识别二维码,即可关注。
如果你觉得好,随手点赞,也是对笔者的肯定,也可以分享此公众号给你更多的人,原创不易