所谓动态注册,就是不用像静态注册那样按规则严格的命名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 -;
} jclass clz = env->FindClass("com/example/zhanghaiqiang/hellojni/HelloJni"); env->RegisterNatives(clz, nativeMethod, sizeof(nativeMethod)/sizeof(nativeMethod[])); return JNI_VERSION_1_4;
}

Android JNI之动态注册的更多相关文章

  1. 利用gdb 调试android jni c动态库

    http://blog.dornea.nu/2015/07/01/debugging-android-native-shared-libraries/ Since I haven't done thi ...

  2. Android JNI之静态注册

    这篇说静态注册,所谓静态注册,就是native的方法是直接通过方法名的规定格式和Java端的声明处代码对应起来的,其对应规则如下: JNIEXPORT <返回值> JNICALL Java ...

  3. Android JNI之数据类型

    JNI中数据类型的意义在于桥接Java数据类型与C数据类型. 简单数据类型: Java Type Native Type Description boolean jboolean unsigned 8 ...

  4. Android 动态注册JNI函数

    1.JNI函数注册方式 在Android开发中,由于种种原因我们需要调用C/C++代码,在这个时候我们就需要使用jni了, jni在使用时要对定义的函数进行注册,这样java才能通过native关键字 ...

  5. Android深入理解JNI(一)JNI原理与静态、动态注册

    前言 JNI不仅仅在NDK开发中应用,它更是Android系统中Java与Native交互的桥梁,不理解JNI的话,你就只能停留在Java Framework层.这一个系列我们来一起深入学习JNI. ...

  6. Android Studio NDK JNI动态注册本地方法

    概述 可能大家觉得javah生成的函数名又臭又长,不太好看.这里可以提供另外一种方法来动态注册c++函数,让其根Java中的native方法关联起来. 实现 这里通过JNIEnv的Resisterna ...

  7. ndk学习20: jni之OnLoad动态注册函数

    一.原理 当在系统中调用System.loadLibrary函数时,该函数会找到对应的动态库, 然后首先试图找到"JNI_OnLoad"函数,如果该函数存在,则调用它 JNI_On ...

  8. Android JNI和NDK学习(03)--动态方式实现JNI(转)

    本文转自:http://www.cnblogs.com/skywang12345/archive/2013/05/23/3092491.html 前面总结了静态实现JNI的方法,本文介绍如何动态实现J ...

  9. JNI原理与静态、动态注册

    前言 JNI不仅仅在NDK开发中应用,它更是Android系统中Java与Native交互的桥梁,不理解JNI的话,你就只能停留在Java Framework层.这一个系列我们来一起深入学习JNI. ...

随机推荐

  1. Monkey and Banana 题解(动态规划)

    Monkey and Banana 简单的动态规划 1.注: 本人第一篇博客,有啥不足还请多多包涵,有好的建议请指出.你以为有人读你博客,还给你提意见. 2.原题 Background: A grou ...

  2. Rancher1.6 部署prometheus

    一.rancher基础配置 镜像:prom/prometheus:latest 映射端口:9090:9090 服务连接: blackbox-exporter cadvisor node-exporte ...

  3. mac篇---iterm2的基本常用命令

    标签 新建标签:command + t 关闭标签:command + w 切换标签:command + 数字 command + 左右方向键 切换全屏:command + enter 查找:comma ...

  4. for of

    1. 遍历范围 for...of 循环可以使用的范围包括: 数组 Set Map 类数组对象,如 arguments 对象.DOM NodeList 对象 Generator 对象 字符串 2. 优势 ...

  5. Flask-Limit使用详细说明

    Flask-Limit详细说明 在flask项目中我们需要对全部或者一部分接口进行限制,又不想造轮子,那怎么办呢? 所以这就是flask-limit出现的原因,不过对于相对复杂的需求,还是自己造轮子吧 ...

  6. 数据可视化之PowerQuery篇(十三)Power BI总计行错误,这个技巧一定要掌握

    https://zhuanlan.zhihu.com/p/102567707 ​前一段介绍过一个客户购买频次统计的案例: Power BI 数据分析应用:客户购买频次分布. 我并没有在文章中显示总计行 ...

  7. Python之爬虫(十六) Scrapy框架中选择器的用法

    Scrapy提取数据有自己的一套机制,被称作选择器(selectors),通过特定的Xpath或者CSS表达式来选择HTML文件的某个部分Xpath是专门在XML文件中选择节点的语言,也可以用在HTM ...

  8. Python网络编程04 /recv工作原理、展示收发问题、粘包现象

    Python网络编程04 /recv工作原理.展示收发问题.粘包现象 目录 Python网络编程04 /recv工作原理.展示收发问题.粘包现象 1. recv工作原理 2. 展示收发问题示例 发多次 ...

  9. 用matplotlib画简单折线图示例

    例1 import numpy as np import matplotlib.pyplot as plt from scipy import stats rx1 = np.array([54.52, ...

  10. C++代码规约--命名约定

    目录 通用命名规则 文件命名 类型命名 变量命名 常量命名 函数命名 宏命名 枚举命名 命名空间命名 命名规则的特例 学习自Google C++编程规约 通用命名规则 函数命名, 变量命名, 文件命名 ...