android NDK 如何使用 JNI 与 Java&Kotlin 语言交互?
主要三种情况
- 自带 JNIEnv 上下文,例如这种参数声明 extern "C" JNIEXPORT void JNICALLn ame(JNIEnv *env, jobject thiz){}
- 主线程反射调用 java/kotlin
- 其他线程反射调用 java/kotlin
情况 1 直接使用即可。
情况 2 通过 android Global JavaVM 获取当前 JNIEnv,例如使用函数 jint GetEnv(JavaVM *vm, void **env, jint version);。
情况3 通过 android Global JavaVM 获取当前 JNIEnv,例如使用函数 jint AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args); jint DetachCurrentThread(JavaVM *vm);;值得注意的是,线程中需要使用全局引用对象来获取类id。这可以在情况1中使用 jobject NewGlobalRef(JNIEnv *env, jobject obj); 函数获取一个全局引用对象。
引用类型在其他线程调用时,需要使用 jobject NewGlobalRef(JNIEnv *env, jobject obj); 函数获取一个全局引用,然后在其他线程使用这个全局引用即可。
class _jobject {};
class _jclass : public _jobject {};
class _jstring : public _jobject {};
class _jarray : public _jobject {};
class _jobjectArray : public _jarray {};
class _jbooleanArray : public _jarray {};
class _jbyteArray : public _jarray {};
class _jcharArray : public _jarray {};
class _jshortArray : public _jarray {};
class _jintArray : public _jarray {};
class _jlongArray : public _jarray {};
class _jfloatArray : public _jarray {};
class _jdoubleArray : public _jarray {};
class _jthrowable : public _jobject {};
具体代码如下所示(中间略有省略非必要代码,不过核心代码基本都在,基本流程已经过测试,可正常在主线程和非主线程与 java/kotlin语言交互):
#include
#include
#include