簡體   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