android 非jni函数调用java类方法

上篇博客已经讲到了 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) != JNI_OK) {
        LOGE("%s: AttachCurrentThread() failed", __FUNCTION__);
        return NULL;
    }
    LOGE("getAssetsImage start 0");
    jclass jclass = env->FindClass("com/example/opengldraw2multicolorbuffer/NativeUtils");
    jmethodID construct_id= env->GetMethodID(jclass,"<init>","()V");
    jobject newNativeUtils = env->NewObject(jclass,construct_id);
    jmethodID getAssetsImageMat_id= env->GetMethodID(jclass,"getAssetsImageMat","(Ljava/lang/String;)J");
    jstring path = env->NewStringUTF("lammy.jpg");
    long imageAddr =  env->CallLongMethod(newNativeUtils, getAssetsImageMat_id, path);
    cv::Mat *srcMat = ( cv::Mat*)imageAddr;// 这里mat像素格式为rgba
    return  srcMat;
}

下面为java层的代码:

public class NativeUtils {
    static {
        System.loadLibrary("lammy");
        System.loadLibrary("opencv_java4");
    }

    public  NativeUtils()
    {

    }
    private static AssetManager assetManager;
    public  static void setAssetManager(AssetManager assetManager2){
        assetManager = assetManager2;
    }


    public long getAssetsImageMat(String imageAssetPath)
    {
        Bitmap bitmap= null;
        try {
            bitmap = BitmapFactory.decodeStream(assetManager.open(imageAssetPath));
        } catch (IOException e) {
            e.printStackTrace();
        }
        Mat mat = new Mat();
        Utils.bitmapToMat(bitmap , mat);
        return mat.getNativeObjAddr();
    }
}

完整demo包含opencv 4.1在android配置,以及图片加载。欢迎大家下载。https://gitee.com/zp2009112217/openglDraw2MultiColorbuffer2

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值