qt android ClassNotFoundException

998 views Asked by At

I'm using Qt (qml) to make an android app but I'm getting errors trying to register native methods to be called from java. In one section on my native code I'm calling java static functions with no problems:

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

Now I'm trying to add some calls from java back to my native code (based on this example) but it fails

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

Results in:

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]]

I've checked the dexdump from classes.dex and the class string matches. All paths in my AndroidManifest.xml are absolute. I've cleaned and rebuilt. Nothing is getting around that problem and I can't figure out why the static method call works but the object one does not.

(Yes, yet another ClassNotFoundException post but I really have searched for answers already).

edit The original failed method based on creating an object threw a different error so I switched back to use FindClass which gives the ClassNotFound error

UPDATE OK, so I think I've figured out why FindClass is failing: according to this FindClass will search the callstack to figure out which ClassLoader to use. Normally this is fine but I believe Qt for android loads under a different thread so the wrong ClassLoader is getting called.

The link recommends caching the classes in JNI_onLoad but with Qt that's behind the scenes. Is there some other place where I could cache class id's on the main thread instead of the qt thread?

1

There are 1 answers

0
ryan0270 On BEST ANSWER

To answer my own question for completeness ...

The reason it failed to find the classes was Qt runs on a different thread than the main java thread, which caused the java classloader to fail in the lookup (see link in question update).

As a solution I added a JNI_onLoad function in one of my cpp files, which is called on the main java thread so the class lookup works correctly.