Android音视频开发入门(2)MediaPlayer 生命周期及create()分析

mOpenSubtitleSources = new Vector();

//通过Binder机制获取到原生的OPS服务

IBinder b = ServiceManager.getService(Context.APP_OPS_SERVICE);

mAppOps = IAppOpsService.Stub.asInterface(b);

//通过之后获取到的服务,就能使用native_setup方法开始创建MediaPlayer了,而且还是软引用,

//接下来就是放在C++层去创建MediaPlayer了

native_setup(new WeakReference(this));

}

MediaPlayer构造函数总结

  1. 定义Looper

  2. 初始化一个TimeProvider

  3. 通过Binder获取原生ops服务

  4. 进入c++层创建一个弱引用的MediaPlayer

所以接下来我们就进入C++层,去分析Native层如何创建MediaPlayer的了。

在分析native_setup之前,请注意 .so文件一般都是在静态代码块中加载的。在MediaPlayer中有一段静态代码块,用于加载和链接库文件media_jni.so

static {

System.loadLibrary(“media_jni”);

native_init();

}

所以我们要去查看 "media_jni"这个c代码,Android Studio是看不到JNI文件的

我们要去Android源码大全这上面去找,代码是通过 loadLibrary(xxx_jni)加载的,那么我的搜索关键字就是 libxxx_jni

然后我们就找到目录/frameworks/base/media/jni下的android_media_MediaPlayer.cpp文件,从它来分析,因为它的第一个函数 android_media_MediaPlayer_init就是从Java静态代码快调过来的nativie_init

//android_media_MediaPlayer.cpp

static void

android_media_MediaPlayer_native_init(JNIEnv *env) {

//类的句柄

jclass clazz;

//这里通过Native层调用Java层,获取MediaPlayer对象

clazz = env -> FindClass(“android/media/MediaPlayer”);

if (clazz == NULL) {

//判空

return;

}

//获取成员变量mNativeContext,它是一个long型,实际对应的是一个内存地址

fields.context = env -> GetFieldID(clazz, “mNativeContext”, “J”);

if (fields.context == NULL) {

return;

}

fields.post_event = env -> GetStaticMethodID(clazz, “postEventFromNative”,

“(Ljava/lang/Object;IIILjava/lang/Object;)V”);

if (fields.post_event == NULL) {

return;

}

}

init方法总结

  1. 被通知init后,从Java层获取一个MediaPlayer

  2. 从MediaPlayer获取一些变量

  3. 从MediaPlayer获取 postEventFromNative()并执行

这个方法顾名思义:Native通知Java层,我初始化好了,你可以开始做一些事情了。

这个时候我们就要去Java层中看 postEventFromNative()这个方法做什么了。

private static void postEventFromNative(Object mediaplayer_ref,

int what, int arg1, int arg2, Object obj)

{

//得到弱引用的MediaPlayer

final MediaPlayer mp = (MediaPlayer)((WeakReference)mediaplayer_ref).get();

if (mp == null) {

return;

}

//如果handler不为空,则发送一条message

if (mp.mEventHandler != null) {

Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj);

mp.mEventHandler.sendMessage(m);

}

}

postEventFromNative总结

总的来说,就是拿到Native层创建好的MediaPlayer,并且向Handler发送一条message,至于后面做了啥之后再讲。

我们之前在create()的时候,创建MediaPlayer之后,会走native_setup方法,我们来看看这个方法做了什么:

//android_media_MediaPlayer.cpp

static void

android_media_MediaPlayer_native_setup(JNIEnv *env, jobject thiz, jobject weak_this)

{

ALOGV(“native_setup”);

sp mp = new MediaPlayer();

// 给MediaPlayer创建一个Listener,便于我们在Java层设置的 setPrepareListener、setOnCompleteListener能产生回调

sp listener = new JNIMediaPlayerListener(env, thiz, weak_this);

mp->setListener(listener);

// 对于Java层来说,C++中的MediaPlayer是不透明的,也无需关心其对应的逻辑,各司其职就行了

setMediaPlayer(env, thiz, mp);

}

<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值