美文网首页
动态注册与静态注册

动态注册与静态注册

作者: 禅座 | 来源:发表于2019-06-14 13:50 被阅读0次

    静态注册

    每个class都需要使用javah生成一个头文件,并且生成的名字很长书写不便;初次调用时需要依据名字搜索对应的JNI层函数来建立关联关系,会影响运行效率
    用javah 生成头文件方便简单

    动态注册

    使用一种数据结构JNINativeMethod来记录java native函数和JNI函数的对应关系
    移植方便(一个java文件中有多个native方法,java文件的包名更换后)

    自己实现动态注册(具体原理不进行深入,可以自己参考源码,从System.loadLibrary拆解)

    //FileUtils
    public class FileUtils {
    public static native void diff(String path,String pattern_path,int fileNum);
    static {
        //不需要后缀是因为内部有进行判断
        System.loadLibrary("native-lib");
    }
    }
    

    native-lib.c

    //为了将log输出到控制台
    #include <android/log.h>
    #include <assert.h>
    
    //int __android_log_print(int prio, const char* tag, const char* fmt, ...)
    #define TAG "Tim_JNI"
    #define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
    # define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
    
    
    JNIEXPORT void JNICALL native_diff
            (JNIEnv *env, jclass clazz, jstring path, jstring pattern_Path, jint file_num)
    {
        LOGI("JNI begin 动态注册的方法 ");
    }
    
    
    //JNINativeMethod是一个结构体,gmethods是一个结构体数组,定义的是需要注册的方面名,对应jni的方法名,方法的返回值已经参数签名
    //typedef struct {  
    // const char* name; /*Java 中函数的名字*/  
    // const char* signature; /*描述了函数的参数和返回值*/  
    // void* fnPtr; /*函数指针,指向 C 函数*/  
    // } JNINativeMethod;
    static const JNINativeMethod gMethods[] = {
            {
                    "diff","(Ljava/lang/String;Ljava/lang/String;I)V",(void*)native_diff
            }
    };
    
    
    //进行方法注册
    static int registerNatives(JNIEnv* engv)
    {
        LOGI("registerNatives begin");
        jclass  clazz;
        //com/zzq/tim/dn_lsn_9/FileUtils 是diff方法所在的路径
        clazz = (*engv) -> FindClass(engv, "com/zzq/tim/dn_lsn_9/FileUtils");
    
        if (clazz == NULL) {
            LOGI("clazz is null");
            return JNI_FALSE;
        }
        //if里面的条件判断是仿照官方的写法
        if ((*engv) ->RegisterNatives(engv, clazz, gMethods, NELEM(gMethods)) < 0) {
            LOGI("RegisterNatives error");
            return JNI_FALSE;
        }
        return JNI_TRUE;
    }
    
    
    //重写JNI_OnLoad实现,如果找到JNI_OnLoad实现,则会执行动态注册,否则就会进行静态注册
    JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
    {
    
        LOGI("jni_OnLoad begin");
    
        JNIEnv* env = NULL;
        jint result = -1;
    
        if ((*vm)->GetEnv(vm,(void**) &env, JNI_VERSION_1_4) != JNI_OK) {
            LOGI("ERROR: GetEnv failed\n");
            return -1;
        }
        assert(env != NULL);
    
        registerNatives(env);
    
        return JNI_VERSION_1_4;
    }
    

    相关文章

      网友评论

          本文标题:动态注册与静态注册

          本文链接:https://www.haomeiwen.com/subject/quxrxctx.html