Android JNI之动态注册

所谓动态注册,就是不用像静态注册那样按规则严格的命名native方法,而是在加载so库的时候完成这个从Java方法到native方法的匹配工作,而这个匹配工作,需要我们写native代码来完成。下面直入正题看看怎么写。

涉及的几个函数和实体(结构体)

  1. JavaVM * 
    指针,指向加载当前动态库的java虚拟机
  2. JNIEnv * 
    指针,指向当前使用的JNI版本,JNI中已定义的方法可以通过它来调用
  3. jint JNI_OnLoad(JavaVM *vm, void *reserved)函数 
    动态库加载的入口,调用System.loadLibrary()方法加载动态库后会回调该函数
  4. jclass FindClass(JNIEnv *env, const char *name)函数 
    根据name中传入的Java全路径类名,找到某个Java类(包路径用'/'分割)
  5. jint RegisterNatives(JNIEnv *env, jclass clazz, const JNINativeMethod *methods, jint nMethods)函数
    注册native方法
  6. JNINativeMethod结构体
    typedef struct { 
    
        char *name; 
    
        char *signature; 
    
        void *fnPtr; 
    
    } JNINativeMethod; 

    定义一个Java中声明的方法和native中实现的方法的对应关系

  7. jint GetEnv(JavaVM *vm, void **env, jint version)函数
    获取当前jvm环境的JNI环境指针

具体实现

废话不多见代码:

// native方法实现
void nativeDynamicLog(JNIEnv *evn, jobject obj){

}

// 声明待注册的native方法数组,结构体三个参数分别表示Java文件中声明的方法名、方法特征、native中的方法的指针
JNINativeMethod nativeMethod[] = {{"dynamicLog", "()V", (void*)nativeDynamicLog},};

// 重载jni.h中的JNI_OnLoad方法
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *jvm, void *reserved) {

    JNIEnv *env;
    // JNI_VERSION_1_4是jni.h中定义好的常量,根据使用的sdk版本不同已定义的常量有所差异,具体见jni.h代码
    if (jvm->GetEnv((void**) &env, JNI_VERSION_1_4) != JNI_OK) {
        return -1;
    }
    
    jclass clz = env->FindClass("com/example/zhanghaiqiang/hellojni/HelloJni");

    env->RegisterNatives(clz, nativeMethod, sizeof(nativeMethod)/sizeof(nativeMethod[0]));


    return JNI_VERSION_1_4;
}

 

转载于:https://www.cnblogs.com/duanzi6/p/7474638.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值