繁体   English   中英

Android Qt 5.3应用程序如何加载自定义Java类?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM