FindClass de qualquer segmento no Android JNI
A página de dicas JNI do Android menciona issoFAQ: Por que o FindClass não encontrou minha turma? Eles mencionam várias soluções e a última opção é essa:
Armazene em cache uma referência ao objeto ClassLoader em algum lugar e emita chamadas loadClass diretamente. Isso requer algum esforço.
Então, eu tentei fazê-lo funcionar e parece que, não importa o que, esse método simplesmente não funciona para mim. Eventualmente, eu percebi como usar o ClassLoader, mas não funciona se de um thread nativo eu tentar loadClass que ainda não foi tocado / carregado. Essencialmente, é idêntico ao env-> FindClass no comportamento quando chamado de um thread nativo, com a exceção de que ele não retornará 0 para classes que já foram usadas no aplicativo. Qualquer idéia se eu não acertei, ou é impossível acessar classes de um thread nativo que ainda não foram usados / carregados.
EDITAR: Eu vou dar mais informações para explicar o que exatamente eu quero dizer. Há JNI regularenv->FindClass(className)
e outro que eu escrevimyFindClass(env, className)
que usa cacheClassLoader->loadClass
.
A classe que estou tentando acessar do c / c ++ nativo é "com / noname / TestClient". Dentro do myFindClass eu também uso env-> FindClass e registro o valor que ele retorna:
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));
...
}
Então, eu tenho essas 3 combinações para explicar o problema.
1)
//inside JNI_OnLoad thread
myFindClass(env, "com/noname/TestClient");
...
//inside native thread created by pthread_create
myFindClass(env, "com/noname/TestClient");
Eu recebo este logcat:
myFindClass ("com / noname / TestClent") => c0: 0x41b64558, c1: 0x41b64558, c0 e c1 são os mesmos: 1
...
myFindClass ("com / noname / TestClent") => c0: 0, c1: 0x41b64558, c0 e c1 são os mesmos: 0
2)
//inside JNI_OnLoad thread
env->FindClass("com/noname/TestClient");
...
//inside native thread created by pthread_create
myFindClass("com/noname/TestClient");
Eu recebo este logcat:
myFindClass ("com / noname / TestClent") => c0: 0, c1: 0x41b64558, c0 e c1 são os mesmos: 0
3)
//inside JNI_OnLoad thread
//"com/noname/TestClient" isn't touched from JNI_OnLoad.
...
//inside native thread created by pthread_create
myFindClass(env, "com/noname/TestClient");
Eu recebo este logcat:
myFindClass ("com / noname / TestClent") => c0: 0, c1: 0, c0 e c1 são os mesmos: 1
Basicamente, meu problema é que o ClassLoader não encontra minha classe no terceiro caso. Isso é um bug? O que pode ser feito para corrigir o problema?
EDIT2: Além disso, parece que o ClassLoader :: loadClass é claramente defeituoso. Se eu perguntar myFindClass ("noname / TestClent"), então ele retorna algum lixo, e quando eu uso, ele retorna o jclass de qualquer forma que o aplicativo trava.