Dra*_*ara 23 c++ java java-native-interface android android-ndk
我有一个java对象,它通过JNI调用C++共享对象.在C++中,我保存了对JNIEnv和jObject的引用.
JavaVM * jvm;
JNIEnv * myEnv;
jobject myobj;
JNIEXPORT void JNICALL Java_org_api_init
(JNIEnv *env, jobject jObj) {
myEnv = env;
myobj = jObj;
}
Run Code Online (Sandbox Code Playgroud)
我还有一个GLSurface渲染器,它最终在另一个线程GLThread上调用上面提到的C++共享对象.然后我尝试使用我最初保存的jobject回调到我的原始Java对象,但我想因为我在GLThread上,我得到以下错误.
W/dalvikvm(16101): JNI WARNING: 0x41ded218 is not a valid JNI reference
I/dalvikvm(16101): "GLThread 981" prio=5 tid=15 RUNNABLE
I/dalvikvm(16101): | group="main" sCount=0 dsCount=0 obj=0x41d6e220 self=0x5cb11078
I/dalvikvm(16101): | sysTid=16133 nice=0 sched=0/0 cgrp=apps handle=1555429136
I/dalvikvm(16101): | schedstat=( 0 0 0 ) utm=42 stm=32 core=1
Run Code Online (Sandbox Code Playgroud)
回调Java的代码:
void setData()
{
jvm->AttachCurrentThread(&myEnv, 0);
jclass javaClass = myEnv->FindClass("com/myapp/myClass");
if(javaClass == NULL){
LOGD("ERROR - cant find class");
}
jmethodID method = myEnv->GetMethodID(javaClass, "updateDataModel", "()V");
if(method == NULL){
LOGD("ERROR - cant access method");
}
// this works, but its a new java object
//jobject myobj2 = myEnv->NewObject(javaClass, method);
//this is where the crash occurs
myEnv->CallVoidMethod(myobj, method, NULL);
Run Code Online (Sandbox Code Playgroud)
}
如果我使用env-> NewObject创建一个新的jObject,我可以成功地回调Java,但它是一个新对象,我不想要它.我需要回到我原来的Java对象.
在回调Java之前是否需要切换线程?如果是这样,我该怎么办?
Mār*_*iko 35
从不同的线程访问对象很好.问题是JNI调用将对象作为本地引用.如果要在JNI调用之间保持对jobject的引用,则需要将其作为全局引用:
myobj = env->NewGlobalRef(jObj);
Run Code Online (Sandbox Code Playgroud)
请记住在使用完之后将其释放,否则垃圾收集器将无法收集它并且您将获得内存泄漏:
myEnv->DeleteGlobalRef(myobj);
Run Code Online (Sandbox Code Playgroud)
在这里阅读全局与本地参考.
| 归档时间: |
|
| 查看次数: |
8134 次 |
| 最近记录: |