Reputation: 293
I'm trying to use JNI in Qt. I would like to know where should I put the java classes. There are many posts about JNI on the internet, but they assume you know where to put the classes and only show how to call the methods.
I found that the variable: ANDROID_PACKAGE_SOURCE_DIR must be set. I set this variable, but it didn't work.
I have a folder android in the project root folder. My files tree is something like this:
-root-project
-android
-app1
-MyJavaClass.class
-MyJavaClass.java
The class has this package: package app1;
In the .pro file, I've tried this:
android{
QT += androidextras
ANDROID_PACKAGE_SOURCE_DIR=$$_PRO_FILE_PWD_/android
}
and this:
android{
QT += androidextras
ANDROID_PACKAGE_SOURCE_DIR=$$PWD/android
}
I'm trying to use the class in this way:
int AccessLocalData::fibonacci(int n) {
return QAndroidJniObject::callStaticMethod<jint>("app1/MyJavaClass", "fibonacci", "(I)I", n);
}
The better posts I found were these:
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?
Both of them said to use ANDROID_PACKAGE_SOURCE_DIR, but once this didn't work for me, I think I need a deeper explanation of how this whole thing works.
The error thrown is this:
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
Upvotes: 2
Views: 1518
Reputation: 4582
They should reside in src
folder under your ANDROID_PACKAGE_SOURCE_DIR
.
Lets say I have a java
package org.me.mypack
, then what I do is create the FQ path for the package under:
ANDROID_PACKAGE_SOURCE_DIR/src
Suppose my ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
eventually I will have this path:
$$PWD/android/src/org.me.mypack
and call a static method in my class:
QAndroidJniObject::callStaticMethod<void>("org.me.mypack/Utilities",
"requestPermissions",
"(Landroid/app/Activity;)V",
QtAndroid::androidActivity().object());
So in your case, you ought to create your package path:
ANDROID_PACKAGE_SOURCE_DIR/src/app1
--> $$PWD/android/src/app1
and put your java class file MyJavaClass.java
and other java
classes for the package in that path.
If you haven't already done, check JNI Crash Course, which uses same call as your example, but with different package!
Extending your Qt Android application using JNI
in the example note the file path: //java file android/src/com/kdab/training/MyJavaClass.java
and the call:
return QAndroidJniObject::callStaticMethod<jint>
("com/kdab/training/MyJavaClass" // java class name
, "fibonacci" // method name
, "(I)I" // signature
, n);
Upvotes: 2