从Android JNI的任何线程中找到FindClass

Android的JNI tips页面提到了这个常见问题:为什么FindClass找不到我的类?他们提到了多种解决方案,最后一个选项是:

Cache a reference to the ClassLoader object somewhere handy, and issue loadClass calls directly. This requires some effort.

缓存对ClassLoader对象的引用,并直接发出loadClass调用。这需要一些努力。

So, I tried to get it working and it seems that no matter what, this method simply does not work for me. Eventually, I figured how to use ClassLoader but it won't work if from a native thread I try to loadClass that hasn't been touched/loaded yet. Essentially, it's the identical to env->FindClass in behavior when called from a native thread, with the exception that it won't return 0 for classes that were already use in the app. Any idea if I didn't get it right, or it's impossible to access classes from a native thread that weren't used/loaded yet.

所以,我试着让它起作用,似乎无论如何,这个方法对我都不起作用。最终,我找到了如何使用ClassLoader的方法,但如果我尝试从一个本地线程加载尚未被触摸/加载的类,那么它将无法工作。从本质上讲,它是相同的env - > FindClass当从一个本地调用线程的行为,除了它不会返回0类已经使用的应用程序。你知道如果我没有得到正确的,或从一个本地线程访问类是不可能的,不使用/加载。






EDIT: I'll give more info to explain what exactly I mean. There is regular JNI env->FindClass(className), and another one that I wrote myFindClass(env, className) that uses cached ClassLoader->loadClass.

编辑:我会提供更多的信息来解释我的意思。有常规的JNI env->FindClass(className),还有一个是我编写的myFindClass(env, className),使用缓存的ClassLoader——>loadClass。

The class that I'm trying to access from native c/c++ is "com/noname/TestClient". Inside myFindClass I also use env->FindClass and log value that it returns:

我正在尝试从本机c/c++中访问的类是com/ name/testclient。在myFindClass中,我还使用env->FindClass和它返回的日志值:

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));
    ...
}

Then, I have these 3 combinations to explain the issue.

然后,我有这三个组合来解释这个问题。

1)

1)

//inside JNI_OnLoad thread
myFindClass(env, "com/noname/TestClient");
...

//inside native thread created by pthread_create
myFindClass(env, "com/noname/TestClient");

I get this logcat:

我得到这个logcat:

myFindClass("com/noname/TestClent") => c0:0x41b64558, c1:0x41b64558, c0 and c1 are same: 1
...
myFindClass("com/noname/TestClent") => c0:0, c1:0x41b64558, c0 and c1 are same: 0

查查myFindClass(com/ noname/testclent) => c0:0x41b64558, c1:0x41b64558, c0和c1相同:1…查查查查myFindClass(com/noname/testclent) => c0:0, c1:0x41b64558, c0和c1相同:0

2)

2)

//inside JNI_OnLoad thread
env->FindClass("com/noname/TestClient");
...

//inside native thread created by pthread_create
myFindClass("com/noname/TestClient");

I get this logcat:

我得到这个logcat:

myFindClass("com/noname/TestClent") => c0:0, c1:0x41b64558, c0 and c1 are same: 0

查查查查myFindClass(com/noname/testclent) => c0:0, c1:0x41b64558, c0和c1相同:0

3)

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");

I get this logcat:

我得到这个logcat:

myFindClass("com/noname/TestClent") => c0:0, c1:0, c0 and c1 are same: 1

查查myFindClass(com/ noname/testclent”)=> c0:0, c1:0, c0和c1相同:1

Basically, my issue is that ClassLoader doesn't find my class in the 3rd case. Is it a bug? What can be done to fix the problem?

基本上,我的问题是ClassLoader不能在第三种情况下找到我的类。这是一个错误吗?我们能做些什么来解决这个问题呢?

EDIT2: On top of that, it seems that ClassLoader::loadClass is plainly buggy. If I ask myFindClass("noname/TestClent") then it returns some garbage, and when I use that returned jclass in any way the app crashes.

最重要的是,ClassLoader::loadClass显然存在bug。如果我问myFindClass(“noname/TestClent”),它会返回一些垃圾,当我使用返回的jclass时,应用程序会崩溃。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苦茶子12138

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值