上篇博客已经讲到了 android jni 调用java类方法和成员变量,源于ffmpeg的调用android的硬解码的灵感,则想着,在非jni函数中调用java层代码。便花了点时间研究了下。
大家都知道jni函数中NIEnv *env, jobject instance,一个 是包含的jvm环境一个是 传下来类对象。于是在jni的函数最终保存了env,然后在非jni函数调用,但会失败,报错env无效。
于是就学ffmpeg调用android的java层mediaCodec类一样,
1、JNI_OnLoad中保存虚拟机变量,
2、非jni函数调用AttachCurrentThread获得当前jvm环境
3、创建java类对象,并调用方法。
下面demo为,利用oepncv和assets在jni层调用上层nativeUtils中的getAssetsImageMat方法加载assets中的图片到C++层。
头文件就是注册了getAssetsImage这里就不给出了。下面为cpp
JavaVM *g_jvm = NULL;
JNIEnv *env;
extern "C"
JNIEXPORT
jint JNI_OnLoad(JavaVM *vm, void *res) {
// av_jni_set_java_vm(vm, 0);
// 返回jni版本
g_jvm = vm;
return JNI_VERSION_1_4;
}
// 非jni函数
Mat* getAssetsImage(const char* image)
{
//获取当前线程的jni环境
if (g_jvm->AttachCurrentThread(&env, NULL) !=