1、在android_media_MediaPlayer.cpp 中,定义fields静态变量,里面有两个重要的成员变量。
context: 用来保存创建的mediaplayer.
post_event:用来将JNI层的事件回调给JAVA层。实现:mediaplayer.java中实现了postEventFromNative()函数,发消息给mediaplayer.java中的线程,jni层中,获取postEventFromNative()函数指针,赋给post_event. JNI层就可以通过post_event来将事件回调给java层。
struct fields_t {
jfieldID context;
jfieldID surface_texture;
jmethodID post_event;
};
static fields_t fields;
static void
android_media_MediaPlayer_native_init(JNIEnv *env)
{
jclass clazz;
clazz = env->FindClass("android/media/MediaPlayer");
if (clazz == NULL) {
return;
}
fields.context = env->GetFieldID(clazz, "mNativeContext", "I"); /*指向mediaplayer.java中的私有变量mNativeContext,用来保存cpp层中的mediaplayer对象*/
if (fields.context == NULL) {
return;
}
fields.post_event = env->GetStaticMethodID(clazz, "postEventFromNative", /*指向mediaplayer.java中的postEventFromNative方法*/
"(Ljava/lang/Object;IIILjava/lang/Object;)V");
if (fields.post_event == NULL) {
return;
}
fields.surface_texture = env->GetFieldID(clazz, "mNativeSurfaceTexture", "I");
if (fields.surface_texture == NULL) {
return;
}
}
/*以下是通过set/get Mediplayer来设置和获取Mediaplayer,如果Mediaplayer已经被销毁,就调用setMediaPlayer(env, thiz, 0);*/
static sp<MediaPlayer> getMediaPlayer(JNIEnv* env, jobject thiz)
{
Mutex::Autolock l(sLock);
MediaPlayer* const p = (MediaPlayer*)env->GetIntField(thiz, fields.context);
return sp<MediaPlayer>(p);
}
static sp<MediaPlayer> setMediaPlayer(JNIEnv* env, jobject thiz, const sp<MediaPlayer>& player)
{
Mutex::Autolock l(sLock);
sp<MediaPlayer> old = (MediaPlayer*)env->GetIntField(thiz, fields.context);
if (player.get()) {
player->incStrong(thiz);
}
if (old != 0) {
old->decStrong(thiz);
}
env->SetIntField(thiz, fields.context, (int)player.get());
return old;
}