Android的JNI提示页面提到了这个FAQ:为什么FindClass找不到我的课程? 他们提到了多个解决方案,最后一个选项就是这个:
在某个地方缓存对ClassLoader对象的引用,并直接发出loadClass调用.这需要一些努力.
所以,我试图让它工作,似乎无论如何,这种方法根本不适合我.最后,我想到了如何使用ClassLoader但是如果从本机线程尝试未被触摸/加载的loadClass它将无法工作.本质上,当从本机线程调用时,它与行为中的env-> FindClass相同,但是对于已在应用程序中使用的类,它不会返回0.任何想法,如果我没有正确,或者无法从原生线程访问尚未使用/加载的类.
编辑:我会提供更多信息来解释我的意思.有常规的JNI env->FindClass(className),我写的另一个myFindClass(env, className)使用缓存ClassLoader->loadClass.
我试图从本机c/c ++访问的类是"com/noname/TestClient".在myFindClass里面我也使用它返回的env-> FindClass和log值:
jclass myFindClass(JNIEnv * env, const char* name)
{
...
jclass c0 = env->FindClass(name);
jclass c1 = (jclass)env->CallObjectMethod(ClassLoader,
MID_loadClass, envNewStringUTF(name));
dlog("myFindClass(\"%s\") => c0:%p, c1:%p, c0 and c1 are same: %d",
name, c0, c1, env->IsSameObject(c0, c1));
...
}
Run Code Online (Sandbox Code Playgroud)
然后,我有这三种组合来解释这个问题.
1)
//inside JNI_OnLoad thread
myFindClass(env, "com/noname/TestClient");
...
//inside native thread created by pthread_create
myFindClass(env, "com/noname/TestClient");
Run Code Online (Sandbox Code Playgroud)
我得到这个logcat:
myFindClass("com/noname/TestClent")=> c0:0x41b64558,c1:0x41b64558,c0和c1相同:1
...
myFindClass("com/noname/TestClent")=> c0:0,c1:0x41b64558, c0和c1相同:0
2)
//inside JNI_OnLoad …Run Code Online (Sandbox Code Playgroud)