• 从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时,应用程序会崩溃。

  • 相关阅读:
    Dubbo启动时检查依赖
    大学宿舍IP一键视频对讲
    分布式技术材料整理
    【JavaSE】异常处理
    Vue官方文档(43):在全局注册组件中使用函数式的组件
    CMake教程-第 7 步:添加系统自省功能
    python之字符串及操作相关知识
    图片格式大全
    Linux 中搭建 主从dns域名解析服务器
    javaScript进阶面向对象ES6【正则表达式概述、正则表达式在 JavaScript 中的使用、正则表达式中的特殊字符、正则表达式中的替换】
  • 原文地址:https://blog.csdn.net/cqn2bd2b/article/details/125378843