实践出真知之MediaPlayer分析篇(我是菜鸟)

学习实践(由于最近也恰好想学习一下service 所以看了一下mediaplayer)



该图为MediaPlayer 的 状态转换图。

Frameworks/base/media/java/android/media/MediaPlayer.java

果断从MediaPlayer.create 该静态方法开始 ,该方法初始化MediaPlayer,并且获取到一个实例


构造函数走起


Looper 一直也没有完全的明白,但是知道差不多是handle的功能,暂时留着以后学习


static JNINativeMethod gMethods[] = {

{"native_setup" , "Ljava/lang/Object;)V", (void *)android_media_MediaPlayer_native_setup)

看着舒服,只传了一个Object 返回值为void 爽,不像以前看什么都蒙。

注意 native_setup为非静态方法,所以再JNI层中的第二个参数是jobject 也就是java层的mediaplayer对象


这里有一个问题 jobject thiz mediaplayer的实例对象,第三个参数jobject weak_this mediaplayer的弱引用,有什么区别呢?

sp mp = new MediaPlayer(); 实际上只做了一些参数的赋值的初始化工作

下面才是重头戏,关于回调什么的乱七八糟的事情。

下面完成的这个JNIMediaPlayerListener 将一个 初始化绑定了javaMediaPlayer实例的listener传给了 MediaPlayer.cpp 用于将来的回调事件

回调过程稍微一提示()

setListener(listenter);

/frameworks/base/media/libmedia/mediaplayer.cpp



JNI层看那个notify


看下面那个mClass 和那个mObject  还有那个 构造函数 很清晰吧

看看实现



这个fields.post_event就是那个所谓的方法名,所以就是调用fields.post_event这个名字的函数 然后 实例也有 数据也有了。

接下来看最后执行的这个setMediaPlayer(env,thiz,mp);

Thiz Java层的实例,mpC测的一个实例


源代码中的描述

在java不透明的区域展示给我们一个 新的 C++ MediaPlayer实例


 由于在源码中 还没有找到这个play.get()方法 故这里只能猜测一下了,主要是为了绑定

然后继续回到MediaPlayer.java::create(Context context , int resid)

设置数据资源设置开始位置,并且 获取长度





是第三个 返回值为void  三个参数 第一个参数java.io.FileDescriptor,第二个long -> J,第三个long ->J 为引用对象之间可以不加分号。



首先获取绑定的那个 mp 获取一个fd(关于音频文件的)

process_media_player_call()

在分析这个方法的时候得看一下mp->setDataSource这个方法



获取一个 MediaPlayerService 看到这的时候 挡住了一下没有找到这个getMediaPlayerService方法 找了半天后来才找到该方法并没有定义在mediaplayer.cpp中,

而是定义在一个/frameworks/base/media/libmedia/IMediaDethNotifier.cpp中定义的 定义如下


在学习Camera 的时候已经遇到过这种形式了,所以很清晰是binder获取service实例

以后的调用中就等于直接调用MediaPlayerService实例了


继续回到mediaplayer.cpp 中的setDataSource(int fd,int64_t offset , int64_t length)

     Sp player(service->create()) 其实service->create()获取的是个client

也就是Service 的内部类 继承了BnMediaPlayer 这个和Camera 一样的

然后就setDataSource(player)

开始执行JNI中的process_dedia_player_call,没什么太大的意义

继续回到java



关闭文件流,然后准备mp



因为没有Surface 故该函数实际上没有什么意义

继续回到java层 现在将java层的mp 返还给ap侧,然后可以开始start()


这个Awake(true)是为了 视频屏幕不黑

JNI 不解释

先获取 一个MediaPlayer 然后 ->start()


这个mPlayer 就是那个BnMediaPlayer



现在只知道这个p mPlayer 这个mPlayer是什么时候创建的呢




这是后明白了 通过 fd文件 判断 player的类型,然后createPlayer




Return 这个 P

在 这里根据playerType的类型建立不同的播放器:对于大多数情况,类型将是PV_PLAYER,这时会调用了new PVPlayer()建立一个PVPlayer,然后将其指针转换成MediaPlayerBase来使用;对于Mini文件的情况,类型为 SONIVOX_PLAYER,将会建立一个MidiFile最后一个就不清楚了


值 得注意的是PVPlayerMidiFile两个个类都是继承MediaPlayerInterface得到的,而 MediaPlayerInterface又是继承MediaPlayerBase得到的,因此者具有相同接口类型。只有建立的时候会调用各自的构造函 数,在建立之后,将只通过MediaPlayerBase接口来MediaPlayerBase控制它们。  

有个地方还需要注意





然后这个PVPlayer.setDataSource()

最后start的时候就是调用这个PVPlayer.start()

目前 暂时到这 由于PVPlayer 没有分析出来,暂时留空间,以待后面分析。



http://blog.csdn.net/chang_xing/article/details/7972725 该文章的有些内容作为了参考,在此谢谢作者!







你可能感兴趣的:(JNI学习篇)