我通过调用返回jobject值的本机代码来创建Java对象。
Java代码:
Object myObj = nativeCreateObject();
原生代码:
jobject* hold_ref;
JNIEXPORT jobject JNICALL
nativeCreateObject(JNIEnv *env ...) {
.....
result = env->NewGlobalRef(jobj);
hold_ref = &result;
return result;
}
我的问题是:我是否可以稍后使用hold_ref在本机层中通过引用释放myObj? 例如 本机代码:
*hold_ref = NULL;
然后Java层中的myObj为空? 如果没有,我怎么能用本机代码发布这个对象?
答案 0 :(得分:2)
我不确定,你想要实现什么,但这是基本的工作方式:
我是否可以稍后使用hold_ref在本机层中通过引用释放myObj?
是的,您可以而且应该使用env->DeleteGlobalRef(myObj)
释放您创建的全局引用,以便垃圾收集器可以清理并最终销毁该对象。
然后Java层中的myObj为空?如果没有,我怎么能用本机代码发布这个对象?
当您从jni本机代码中删除引用时,您的Java变量无法转为null magicaly。 Java本身拥有一个引用来防止垃圾收集对象被删除。
您可能希望以这种方式使用它:
C ++
jobject* hold_ref;
JNIEXPORT jobject JNICALL nativeCreateObject(JNIEnv *env ...) {
.....
result = env->NewGlobalRef(jobj);
hold_ref = &result;
return result;
}
JNIEXPORT void JNICALL nativeDestroyObject(JNIEnv *env ...) {
.....
env->DeleteGlobalRef(jobj);
hold_ref = nullptr;
}
JAVA
// Creates two references (native and local variable)
Object myObj = nativeCreateObject();
// Deletes the native reference, but not the local one
nativeDeleteObject(myObj);
// myObj != null
myObj = null;
// now there is no reference to your created object
// the garbage collector may destroy it any time
如果你想在某种程度上使你的对象无效,我建议管理状态并抛出一个异常,如果对象被无效这样:
class MyInvalidateableObject {
private boolean invalidated = false;
public void invalidate() {
this.invalidated = true;
}
public void foo() {
if (invalidated)
throw new IllegalStateException("Object has been invalidated");
... // do the normal stuff
}
}
只需使用本机代码调用对象上的invalidate()
即可防止再次使用它。