使用JNI时,Qt在哪里查找java类(示例代码)

栏目: java · 发布时间: 2021-04-13

简介  这篇文章主要介绍了使用JNI时,Qt在哪里查找java类(示例代码)以及相关的经验技巧,文章约4530字,浏览量305,点赞数3,值得参考!

我正试图在Qt中使用JNI。我想知道我应该把java类放在哪里。在互联网上有很多关于JNI的帖子,但他们假设你知道在哪里放课,只展示如何调用这些方法。

我发现必须设置变量:ANDROID_PACKAGE_SOURCE_DIR。我设置了这个变量,但它没有用。

我在项目根文件夹中有一个文件夹android。我的文件树是这样的:

-root-project
    -android
        -app1
            -MyJavaClass.class
            -MyJavaClass.java

该课程有这个包:package app1;

在.pro文件中,我试过这个:

android{
    QT += androidextras
    ANDROID_PACKAGE_SOURCE_DIR=$$_PRO_FILE_PWD_/android
}

还有这个:

android{
    QT += androidextras
    ANDROID_PACKAGE_SOURCE_DIR=$$PWD/android
}

我试图以这种方式使用该类:

int AccessLocalData::fibonacci(int n) {
    return QAndroidJniObject::callStaticMethod<jint>("app1/MyJavaClass", "fibonacci", "(I)I", n);
}

我找到的更好的帖子是这些:

Using Qt/C++ to call Java code through JNI. FindClass does not find class

How to use QAndroidJniObject to call Java code from inside Qt?

他们两个都说使用ANDROID_PACKAGE_SOURCE_DIR,但是一旦这对我不起作用,我想我需要更深入地解释这一切是如何工作的。

抛出的错误是这样的:

W System.err: java.lang.ClassNotFoundException: Didn't find class "app1.MyJavaClass" on path: DexPathList[[],nativeLibraryDirectories=[/vendor/lib, /system/lib]]
W System.err:   at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
W System.err:   at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
W System.err:   at java.lang.ClassLoader.loadClass(ClassLoader.java:469)
W System.err:   Suppressed: java.lang.ClassNotFoundException: Didn't find class "app1.MyJavaClass" on path: DexPathList[[zip file "/data/app/org.qtproject.example.INF628-1/base.apk"],nativeLibraryDirectories=[/data/app/org.qtproject.example.INF628-1/lib/arm, /data/app/org.qtproject.example.INF628-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]
W System.err:       at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
W System.err:       at java.lang.ClassLoader.loadClass(ClassLoader.java:511)
W System.err:       at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
W System.err:       ... 1 more
W System.err:       Suppressed: java.lang.ClassNotFoundException: app1.MyJavaClass
W System.err:           at java.lang.Class.classForName(Native Method)
W System.err:           at java.lang.BootClassLoader.findClass(ClassLoader.java:781)
W System.err:           at java.lang.BootClassLoader.loadClass(ClassLoader.java:841)
W System.err:           at java.lang.ClassLoader.loadClass(ClassLoader.java:504)
W System.err:           ... 2 more
W System.err:       Caused by: java.lang.NoClassDefFoundError: Class not found using the boot class loader; no stack trace available
答案

它们应该位于src下的ANDROID_PACKAGE_SOURCE_DIR文件夹中。让我说我有一个javaorg.me.mypack,然后我做的是创建包下的FQ路径:ANDROID_PACKAGE_SOURCE_DIR/src

假设我的ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android

最终我会有这条道路:

$$PWD/android/src/org.me.mypack

并在我的类中调用静态方法:

QAndroidJniObject::callStaticMethod<void>("org.me.mypack/Utilities",
                                        "requestPermissions",
                                        "(Landroid/app/Activity;)V",
                                        QtAndroid::androidActivity().object());

所以在你的情况下,你应该创建你的包路径:

ANDROID_PACKAGE_SOURCE_DIR/src/app1 - > $$PWD/android/src/app1

并将您的java类文件MyJavaClass.java和其他java类放在该路径中的包中。

如果您还没有完成,请查看JNI速成课程,该课程使用与您的示例相同的调用,但使用不同的包!

Extending your Qt Android application using JNI

在示例中注意文件路径://java file android/src/com/kdab/training/MyJavaClass.java和调用:

return QAndroidJniObject::callStaticMethod<jint>
 ("com/kdab/training/MyJavaClass" // java class name
 , "fibonacci" // method name
 , "(I)I" // signature
 , n);

以上就是本文的全部内容,希望对大家的学习有所帮助,版权归原作者或者来源机构所有,感谢作者,如果未能解决你的问题,请参考以下文章。

mac实现jni的demo

如何在JNI层中修改java类对象(示例代码)

Qt sqlite插件在哪里寻找扩展库(示例代码)

jni使用javap查看java类方法签名(示例代码)

如何使用JNI管理C ++代码中的静态变量?