0

How can I call a c++ method from a Java activity?

This is my Java code:

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");
  }
}

This is my c++ code:

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);
}

When the Java code calls the resultRead function, my app crashes with this exception:

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)

Any suggestion?

Fausto01
  • 171
  • 14
  • Not familiar with that use case but the error message seems to help: `Can't create handler inside thread that has not called Looper.prepare()` – RoQuOTriX Sep 28 '21 at 13:22
  • I'm not familiar with Java, do I have to call Looper.prepare() in the activity constructor? – Fausto01 Sep 28 '21 at 13:24
  • I implement standard JNI_OnLoad function. It's used to register all native functions. I don't see it in your code. Look here for more details: https://www.kdab.com/qt-android-episode-5/ Beware of this bug also: https://bugreports.qt.io/browse/QTBUG-70114 – Alexander Dyagilev Sep 29 '21 at 16:40
  • I just followed this guide: https://doc.qt.io/qt-5/qtandroidextras-jnimessenger-example.html. I'll try your method, thank you. – Fausto01 Sep 29 '21 at 20:14

0 Answers0