Android JNI开发(3)--引用类型

本文详细介绍了NDK开发中三种引用类型:局部引用、全局引用和弱全局引用的区别及使用方法。包括每种引用类型的创建方式、使用特点、释放机制,并提供示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

NDK开发中的引用类型分为三种:局部引用(Local Reference)、全局引用(Global Reference)、弱全局引用(Weak Global Reference)

1、 局部引用

通过NewLocalRef和各种JNI接口创建(FindClass、NewObject、GetObjectClass和NewCharArray等)。会阻止GC回收所引用的对象,不能跨函数使用,不能跨线程使用。函数返回后局部引用所引用的对象会被JVM自动释放,或调用DeleteLocalRef主动释放。
以下几种局部引用的创建方式:

jclass cls_string = (*env)->FindClass(env, "java/lang/String");
jcharArray charArr = (*env)->NewCharArray(env, len);
jstring str_obj = (*env)->NewObject(env, cls_string, cid_string, elemArray);
jstring str_obj_local_ref = (*env)->NewLocalRef(env,str_obj);   // 通过NewLocalRef函数创建
等

主动删除一个局部引用调用DeleteLocalRef,如下:

(*env)->DeleteLocalRef(env,object);

我们不可以使用static来修饰局部引用,让它下次使用,这样会造成野指针。

2、全局引用

调用NewGlobalRef基于局部引用创建,会阻GC回收所引用的对象。可以跨方法、跨线程使用。JVM不会自动释放,必须调用DeleteGlobalRef手动释放(*env)->DeleteGlobalRef(env,object);

jclass localclazz
jclass globalclazz
……
localclazz = (*env)->FindClass(env,"java/lang/String");//局部
globalclazz = (*env)->NewGlobalRef(env,localclazz );//将布局引用的对象转成全局的引用对象
……
(*env)->DeleteLocalRef(env,localclazz );//需要主动删除全局应用

3、弱全局引用

调用NewWeakGlobalRef基于局部引用或全局引用创建,不会阻止GC回收所引用的对象,可以跨方法、跨线程使用。引用不会自动释放,在JVM认为应该回收它的时候(比如内存紧张的时候)进行回收而被释放。或调用DeleteWeakGlobalRef手动释放。(*env)->DeleteWeakGlobalRef(env,object)

jclass cls_string = (*env)->FindClass(env, "java/lang/String");
g_cls_string = (*env)->NewWeakGlobalRef(env,cls_string);//基于局部引用创建弱全局引用

我们不知道弱引用是否一应被回收,所以需要判断一下有效性:
可以使用IsSameObject函数检验一个弱全局引用是否仍然指向活动的类实例,例如:

if(JNI_FALSE == (*env)->IsSameObject(env,weakGlobalClazz,NULL)){
/*对象仍然处于活动状态且可以使用*/
}else{
/*对象被垃圾回收期收回,不能使用*/
}

当然这个方法,也可以判断两个引用(局部、全局、弱全局)是否指向同一个对象,方法为:

(*env)->IsSameObject(env, obj1, obj2)

如果obj1和obj2指向相同的对象,则返回JNI_TRUE(或者1),否则返回JNI_FALSE(或者0)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值