1

我正在使用 Qt (qml) 制作一个 android 应用程序,但我在尝试注册要从 java 调用的本机方法时遇到错误。在我的本机代码的一部分中,我毫无问题地调用了 java 静态函数:

void NotificationClient::powerOff() {
    QAndroidJniObject::callStaticMethod<void>("com/my_app/Utils",
                                       "powerOff",
                                       "()V"
                                        );
}

现在我正在尝试将一些来自 java 的调用添加回我的本机代码(基于此示例),但它失败了

QAndroidJniEnvironment env;
jclass objectClass = env->FindClass("com/my_app/Utils");

结果是:

Pending exception java.lang.ClassNotFoundException: Didn't find class "com.my_app.Utils" on path: DexPathList[[directory "."],nativeLibraryDirectories=[/system/lib, /vendor/lib, /system/lib, /vendor/lib]]

我检查了 classes.dex 中的 dexdump 并且类字符串匹配。我的 AndroidManifest.xml 中的所有路径都是绝对路径。我已经清理并重建了。没有什么能解决这个问题,我不知道为什么静态方法调用有效,但对象却没有。

(是的,还有另一个 ClassNotFoundException 帖子,但我真的已经在寻找答案了)。

编辑基于创建对象的原始失败方法引发了不同的错误,所以我切换回使用 FindClass,它给出了 ClassNotFound 错误

更新 好的,所以我想我已经弄清楚 FindClass 失败的原因:根据这个FindClass 将搜索调用堆栈以找出要使用的 ClassLoader。通常这很好,但我相信 Qt for android 在不同的线程下加载,所以错误的 ClassLoader 被调用。

该链接建议在 JNI_onLoad 中缓存类,但使用 Qt 是在幕后。是否有其他地方可以在主线程而不是 qt 线程上缓存类 ID?

4

1 回答 1

1

为了完整起见,回答我自己的问题...

它未能找到类的原因是 Qt 在与主 java 线程不同的线程上运行,这导致 java 类加载器在查找中失败(请参阅有问题的更新链接)。

作为一种解决方案,我在我的一个 cpp 文件中添加了一个 JNI_onLoad 函数,该函数在主 java 线程上调用,因此类查找工作正常。

于 2017-01-12T12:50:30.787 回答