qt android ClassNotFoundException
Я использую 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]]
Я проверил dexdump из classes.dex и совпадения строк классов. Все пути в моем AndroidManifest.xml являются абсолютными. Я убрал и восстановил. Ничто не решает эту проблему, и я не могу понять, почему вызов статического метода работает, а объект - нет.
(Да, еще один пост ClassNotFoundException, но я действительно уже искал ответы).
edit Исходный ошибочный метод, основанный на создании объекта, выдал другую ошибку, поэтому я переключился обратно на использование FindClass, которое выдает ошибку ClassNotFound
ОБНОВЛЕНИЕ ОК, так что я думаю, что я выяснил, почему FindClass не работает: в соответствии с этим FindClass будет искать в стеке вызовов, чтобы выяснить, какой ClassLoader использовать. Обычно это нормально, но я считаю, что Qt для Android загружается из другого потока, поэтому вызывается неправильный ClassLoader.
Ссылка рекомендует кэшировать классы в JNI_onLoad, но с Qt это негласно. Есть ли другое место, где я мог бы кэшировать идентификаторы классов в основном потоке вместо потока qt?
1 ответ
Чтобы ответить на мой вопрос для полноты...
Причина, по которой ему не удалось найти классы, заключалась в том, что Qt работает в потоке, отличном от основного потока Java, что привело к сбою загрузчика классов Java при поиске (см. Ссылку в вопросе update).
В качестве решения я добавил функцию JNI_onLoad в один из моих файлов cpp, который вызывается в основном потоке Java, поэтому поиск класса работает правильно.