[英]How does an Android Qt 5.3 Application load custom Java classes?
我正在将Qt应用程序移植到Android,并与系统的各个部分进行通信,它使用了与该应用程序打包在一起的自定义Java库。 问题是我找不到加载我需要调用的Java类的地方。
通常我会在JNI_OnLoad中执行此操作,但是Qt 5.3将其隐藏在其自己的内部代码中。 这意味着我必须在Qt应用程序启动时从本机线程加载类,因为QApplication是在其自己的线程中启动的。 系统类加载器可在此上下文中使用,但没有一个可以在我的APK中找到类的加载器。
另一个选择是获得将找到本地类的类加载器。 浏览Qt代码时,我看到它在启动时确实抓住了类加载器,但在Qt私有代码中它再次处于关闭状态。 无法从应用程序访问它。
我以为这在Qt Android应用程序中会是一件很普通的事情,但令我惊讶的是我感到惊讶。 我希望我缺少明显的东西。
有谁知道在Qt 5.3应用程序中使用JNI检索Java类实例的正确位置?
忽略错误检查,下面的代码段是我要尝试的操作。 我已验证该类已包含在dex文件中,并具有所需的名称,但从未找到该类(抛出java.lang.NoClassDefFoundError)。
// Given a JNIEnv, find MyClass, and cache it away for later use
jclass localClass = env->FindClass("my/class/in/apk/MyClass");
j_MyClass = reinterpret_cast<jclass>(env->NewGlobalRef(localClass));
env->DeleteLocalRef(localClass);
事实证明,我并没有接受Qt方式。 我自己不能缓存jclass,但是使用Qt类QAndroidJniObject可以达到相同的效果。 在幕后,Qt会在引用时将引用的jclass和jmethod缓存掉。 Qt实现中有一些额外的开销,而不是您自己去做,但是在我的情况下,这不是问题。 从好的方面来说,它大大简化了JNI代码。
总而言之,只需使用QAndroidJniObject类,而无需自己缓存jclass / jmethod引用。
作为一个没有错误检查的狡猾示例:
void JNICALL Java_my_java_class_MyClass_myNativeMethod
(JNIEnv* env, jobject, jobjectArray objectArray)
{
QAndroidJniObject obj(env->GetObjectArrayElement(objectArray, 0));
QAndroidJniObject jstr = obj.callObjectMethod<jstring>("getString");
QString qtstr = jstr.toString();
}
回想起来,这一切都很明显:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.