Qt вызывает метод c из действия java

#java #android #c #qt #qtandroidextras

Вопрос:

Как я могу вызвать метод c из действия Java?

Это мой Java-код:

 public class TestActivity extends QtActivity
{
  public native void resultRead(String maskedPan);

  @Override
  protected void onNewIntent(Intent intent)
  {
    ... do something here with the received intent

    resultRead("result");
  }
}
 

Это мой код на c :

 static void onResultRead(JNIEnv *env, jobject /*thiz*/, jstring value)
{
  qDebug() << env->GetStringUTFChars(value, nullptr);
}

void MyClass::registerJni()
{
  QAndroidJniEnvironment env;
  QAndroidJniObject javaClass("org/test/testproject/TestActivity");
  JNINativeMethod methods[] {{"resultRead", "(Ljava/lang/String;)V", reinterpret_cast<void *>(onResultRead)}};
  jclass objectClass = env->GetObjectClass(javaClass.object<jobject>());
  env->RegisterNatives(objectClass, methods, sizeof(methods) / sizeof(methods[0]));
  env->DeleteLocalRef(objectClass);
}
 

Когда код Java вызывает функцию resultRead, мое приложение завершает работу с этим исключением:

 F art     : art/runtime/java_vm_ext.cc:470] JNI DETECTED ERROR IN APPLICATION: JNI GetObjectClass called with pending exception java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare()
F art     : art/runtime/java_vm_ext.cc:470]   at void android.os.Handler.<init>(android.os.Handler$Callback, boolean) (Handler.java:200)
F art     : art/runtime/java_vm_ext.cc:470]   at void android.os.Handler.<init>() (Handler.java:114)
F art     : art/runtime/java_vm_ext.cc:470]   at void android.app.Activity.<init>() (Activity.java:794)
F art     : art/runtime/java_vm_ext.cc:470]   at void org.qtproject.qt5.android.bindings.QtActivity.<init>() (QtActivity.java:94)
F art     : art/runtime/java_vm_ext.cc:470]   at void org.test.testproject.TestActivity.<init>() (TestActivity.java:12)
 

Есть какие-нибудь предложения?

Комментарии:

1. Не знаком с этим вариантом использования, но сообщение об ошибке, похоже, помогает: Can't create handler inside thread that has not called Looper.prepare()

2. Я не знаком с Java, нужно ли мне вызывать Looper.prepare() в конструкторе действий?

3. Я реализую стандартную функцию JNI_OnLoad. Он используется для регистрации всех собственных функций. Я не вижу этого в вашем коде. Смотрите здесь для получения более подробной информации: kdab.com/qt-android-episode-5 Остерегайтесь также этой ошибки: bugreports.qt.io/browse/QTBUG-70114

4. Я просто следовал этому руководству: doc.qt.io/qt-5/qtandroidextras-jnimessenger-example.html . Я попробую ваш метод, спасибо.