Java call native with callback of anonymous inner class
Lib.kt
package com.practice class Lib { external fun getJniVersion(callback: Callback) interface Callback { fun onResponse(version: String) } init { System.loadLibrary("native-lib") } }
CMakeLists.txt
cmake_minimum_required(VERSION 3.10.2) add_library(native-lib SHARED native-lib.cpp) find_library(log-lib log) target_link_libraries(native-lib ${log-lib})
native-lib.cpp
#include <jni.h> #include <android/log.h> jstring getVersion(JNIEnv *env) { switch (env->GetVersion()) { case JNI_VERSION_1_1: return env->NewStringUTF("JNI_VERSION_1_1"); case JNI_VERSION_1_2: return env->NewStringUTF("JNI_VERSION_1_2"); case JNI_VERSION_1_4: return env->NewStringUTF("JNI_VERSION_1_4"); case JNI_VERSION_1_6: return env->NewStringUTF("JNI_VERSION_1_6"); default: return env->NewStringUTF("UNKNOWN"); } } extern "C" JNIEXPORT void JNICALL Java_com_practice_Lib_getJniVersion(JNIEnv *env, jobject /* this */, jobject callback) { __android_log_print(ANDROID_LOG_DEBUG, "native", "looking for class"); jclass callbackClass = env->GetObjectClass(callback); if (callbackClass != nullptr) { jmethodID methodId = env->GetMethodID(callbackClass, "onResponse", "(Ljava/lang/String;)V"); if (methodId != nullptr) { env->CallVoidMethod(callback, methodId, getVersion(env)); } else { __android_log_print(ANDROID_LOG_DEBUG, "native", "can not find method"); } } else { __android_log_print(ANDROID_LOG_DEBUG, "native", "can not find class"); } }
MainActivity.kt
package com.practice import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) Lib().getJniVersion(object : Lib.Callback { override fun onResponse(version: String) { sample_text.text = version } }) } }
use of deleted global reference error
When I call the Java method with wrong parameter type such as:
env->CallVoidMethod(callback, methodId, "jni version");
I will get below error:
JNI DETECTED ERROR IN APPLICATION: use of deleted global reference
Can't succeed in calling a Java function from a C++ module with JNI
illegal class name error
When I find class with wrong format jclass callbackClass = env->FindClass("com/practice/Lib.Callback");
, I will get error.
A/art: art/runtime/java_vm_ext.cc:410] JNI DETECTED ERROR IN APPLICATION: illegal class name 'com/practice/Lib.Callback'
A/art: art/runtime/java_vm_ext.cc:410] (should be of the form 'package/Class', [Lpackage/Class;' or '[[B')
A/art: art/runtime/java_vm_ext.cc:410] in call to FindClass
A/art: art/runtime/java_vm_ext.cc:410] from void com.practice.Lib.getJniVersion(com.practice.Lib$Callback)
It should be env->FindClass("com/practice/Lib$Callback")
for inner class.