• 从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和它返回的日志值:

    1. jclass myFindClass(JNIEnv * env, const char* name)
    2. {
    3. ...
    4. jclass c0 = env->FindClass(name);
    5. jclass c1 = (jclass)env->CallObjectMethod(ClassLoader,
    6. MID_loadClass, envNewStringUTF(name));
    7. dlog("myFindClass(\"%s\") => c0:%p, c1:%p, c0 and c1 are same: %d",
    8. name, c0, c1, env->IsSameObject(c0, c1));
    9. ...
    10. }

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

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

    1)

    1)

    1. //inside JNI_OnLoad thread
    2. myFindClass(env, "com/noname/TestClient");
    3. ...
    4. //inside native thread created by pthread_create
    5. 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)

    1. //inside JNI_OnLoad thread
    2. env->FindClass("com/noname/TestClient");
    3. ...
    4. //inside native thread created by pthread_create
    5. 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)

    1. //inside JNI_OnLoad thread
    2. //"com/noname/TestClient" isn't touched from JNI_OnLoad.
    3. ...
    4. //inside native thread created by pthread_create
    5. 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时,应用程序会崩溃。

  • 相关阅读:
    【老生谈算法】matlab实现高斯白噪声仿真算法源码——高斯白噪声
    K8S存储总结&持久化存储解决方案(以NFS为例)
    【基础计算机网络1】认识计算机网络体系结构,了解计算机网络的大致模型(下)
    Go语言 String 简介
    git 基础
    解放双手推荐一款阿里开源的低代码工具,YYDS
    《OpenDRIVE1.6规格文档》4
    面试之 top k问题
    arm-linux交叉编译Gstreamer
    Redis常见面试问题总结
  • 原文地址:https://blog.csdn.net/cqn2bd2b/article/details/125378843