JNI Reference
其实是对jobject的分类
局部引用 LocalRef 本地方法栈内有效
全局引用 GlobalRef 虚拟机全局生效 不会被GC回收
若全局引用 WeakGlobalRef 虚拟机全局生效 GC时被回收
以下全都是局部引用:
局部引用最大数量为512个,可能会产生内部泄漏
建议采用下面这种方式
(*env)->PushLocalFrame(env,3);
jobject localobj1 =
(*env)->NewLocalRef(env,message);
jobject localobj2 =
(*env)->NewLocalRef(env,message);
jobject localObj3 =
(*env)->NewLocalRef(env,message);
jobject localObj4 =
(*env)->NewLocalRef(env,message);
(*env)->PopLocalFrame(env,NULL);
GlobalReference
//声明全局引用
jclass cls = (*env)->FindClass(env,"android/os/Message");
globalCls = (*env)->NewGlobalRef(env, cls);
//删除全局引用
(*jvm)->GetEnv(jvm,(void**)&env,JNI_VERSION_1_6);
if(globalCls!=NULL) {
(*env)->DeleteGlobalRef(env, globalCls);
}
//全局化field和methodId
whatField = (*env)->GetFieldID(env,cls,"what","I");
obtainMethod =(*env)->GetStaticMethodID
(env,cls, "obtain","()Landroid/os/Message;");
初始化
jint JNI_OnLoad(JavaVM* jvm, void* reserved) {
JNIEnv* env = NULL;
if((*jvm)->GetEnv(jvm,(void**)&env,JNI_VERSION_1_6)!=JNI_OK){
return JNI_ERR;
}
//声明全局引用
jclass cls = (*env)->FindClass(env,"android/os/Message");
globalCls = (*env)->NewGlobalRef(env, cls);
//全局化field和methodId
whatField = (*env)->GetFieldID(env,cls,"what","I");
obtainMethod =(*env)->GetStaticMethodID
(env,cls, "obtain","()Landroid/os/Message;");
jclass jnDemoClass = (*env)->FindClass(env,classPathName);
//通过registerNatives调用
(*env)->RegisterNatives(env,jnDemoClass,methods,
sizeof(methods)/sizeof(methods[0]));
return JNI_VERSION_1_6;
}
void JNI_OnUnload(JavaVM* jvm, void* reserved){
JNIEnv* env = NULL;
(*jvm)->GetEnv(jvm,(void**)&env,JNI_VERSION_1_6);
if(globalCls!=NULL) {
(*env)->DeleteGlobalRef(env, globalCls);
}
whatField= NULL;
obtainMethod = NULL;
}
registerNative
//创建一个jni与java的关联表
static JNINativeMethod methods[] = {
{"changeMessageWhatInNative","(Landroid/os/Message;)V",
(void*)changeMessageWhatInNative },
{"getMessageFromNative","()Landroid/os/Message;",
(void*)getMessageFromNative },
};
//通过registerNatives调用,一次registerNative只能注册一个class
(*env)->RegisterNatives(env,jnDemoClass,methods,
sizeof(methods)/sizeof(methods[0]));