一.动态注册和静态注册 注册native方法有两种方式,动态注册和静态注册。... //声明native方法 native String stringFromJNI(); native static int add(int a,int b); } 2.注册函数...:在java中加载动态库的时候,虚拟机会调用JNI库中的JNI_Onload()函数,动态注册就是在这个函数中进行的。...签名 void* fnPtr;//本地函数的指针 } JNINativeMethod; 下面给出这部分的代码: #include #include...第二个函数的签名(II)I表示java中的add函数的形参列表是(int,int),返回值类型也是int类型。 那这个签名有什么作用呢?其实是为了解决java中的函数重载问题。
JNI函数的方法(静态方法)存在一些弊端,本篇将介绍另外一种方法(动态注册)来克服这些弊端。...注册JNI函数的两种方法 静态方法 这种方法我们比较常见,但比较麻烦,大致流程如下: 先创建Java类,声明Native方法,编译成.class文件。...动态注册 我们知道Java Native函数和JNI函数时一一对应的,JNI中就有一个叫JNINativeMethod的结构体来保存这个对应关系,实现动态注册方就需要用到这个结构体。...; } 先仔细看一下上面的代码,看起来好像多了一些代码,稍微解释下,如果要实现动态注册就必须实现JNI_OnLoad方法,这个是JNI的一个入口函数,我们在Java层通过System.loadLibrary...以上就是动态注册JNI函数的方法,上面只是一个简单的例子,如果你还想再实现一个native方法,只需要在JNINativeMethod数组中添加一个元素,然后实现对应的JNI层函数即可,下次我们加载动态库时就会动态的将你声明的方法注册到
JNI方法注册源码分析(JNI_OnLoad|动态注册|静态注册|方法替换) [icon13-png-ed.png] 背景 开发Android应用时,有时候Java层的编码不能满足实际需求,需要通过JNI...此时,C组件开发者可以将本地函数向VM进行注册,以便能加快后续调用native函数的效率。...为了客服这个问题,我们可以通过在.so文件载入初始化时,即JNI_OnLoad函数中,先行将native函数注册VM的native函数链表中去,这样一来,后续每次Java调用native函数都会在VM中...方法是可以重复注册的,无论如何,函数dvmRegisterJNIMethod都是调用另外一个函数dvmUseJNIBridge来继续执行注册JNI的操作。...JNI方法的Java类成员函数 //参数func表示JNI方法的Bridge函数 //参数insns表示要注册的JNI方法的函数地址。
之前使用到JNI中,都是通过javah命令生成对应c/c++中的方法名,其规则为:java的包名+native方法名,我们把它称作静态注册。...JNI还可以使用动态注册,在JNI源码中,安卓系统(PathClassLoader)加载so文件时,首先会调用一个方法:JNI_OnLoad;这是系统预留给外部使用动态注册使用的,今天来使用动态注册的方式调用...String;", (void *) native_stringFromJNI } }; 每个元素中,第一个参数为Java中对应的方法,第二个参数为方法签名,第三个参数为c/c++中的函数指针...总结: 静态注册: 每个class都需要使用javah生成一个头文件,并且生成的名字很长书写不便;初次调用时需要依据名字搜索对应的JNI层函数来建立关联关系,会影响运行效率 用javah 生成头文件方便简单...动态注册: 使用一种数据结构JNINativeMethod来记录java native函数和JNI函数的对应关系 移植方便(一个java文件中有多个native方法,java文件的包名更换后)
声明的 JNI_OnLoad方法,在JNI_OnLoad中进行注册(register_android_media_MediaPlayer), // 在注册过程中,声明了一个gMethods的结构体数组...而JNI_OnLoad的调用处,就是System.loadLibrary 的时候会走到 // 这里,然后进行动态注册 jint JNI_OnLoad(JavaVM* vm, void* /* reserved...JNI 动态注册 根据以上的分析进行实现: java代码: public class FileUtils { public static native void diff(String path...;初次调用时需要依据名字搜索对应的JNI层函数来建立关联关系,会影响运行效率 用javah 生成头文件方便简单 1.javah生一个头文件 操作简单 2.名字很长 书写不方便 3.初次调用的使用...来记录java native函数和JNI函数的对应关系 移植方便,便于维护(一个java文件中有多个native方法,只要修改下gMethods 的映射关系)
今天也给出一个JNI动态注册native方法的例子,如图: ?...是 jdk 自带的一个命令,-jni 参数表示将 class 中用native 声明的函数生成 JNI 规则的函数) 用本地代码(c/c++)实现.h头文件中的函数 将(c/c++)文件编译成动态库(...JVM 查找 native 方法 JVM 查找 native 方法有两种方式: 按照 JNI 规范的命名规则 调用 JNI 提供的 RegisterNatives 函数,将本地函数注册到 JVM 中。...第一个参数:JNIEnv* 是定义任意 native 函数的第一个参数(包括调用 JNI 的 RegisterNatives 函数注册的函数),指向 JVM 函数表的指针,函数表中的每一个入口指向一个...JNI 函数,每个函数用于访问 JVM 中特定的数据结构。
注册native函数 当Java代码中执行Native的代码的时候,首先是通过一定的方法来找到这些native方法。JNI有如下两种注册native方法: 静态注册 根据函数名来找对应的JNI函数。...通过JNI重载JNI_OnLoad()方法,调用registerNativeMethods函数来完成注册工作 下面主要讲一下动态注册,动态注册比较方便jni的移植,而静态注册如果移植到其他的packet...,需要修改所有的jni函数名.加载的效率上,动态注册也优于静态注册 动态注册 System.loadLibrary 首先需要Java层代码通过System.loadLibrary函数加载so库 static..._1_4) 这里调用了GetEnv函数时为了获取JNIEnv结构体指针, 后面通过JNIEnv提供的函数注册native 方法 注册native方法 static int registerNativeMethods...; } //注册函数 参数:java类 所要注册的函数数组 注册函数的个数 if(env->RegisterNatives(clazz, gMethods, methodsNum
这就需要了解JNI方法注册的知识。 5.JNI方法注册 JNI方法注册分为静态注册和动态注册,其中静态注册多用于NDK开发,而动态注册多用于Framework开发。...我们知道,静态注册就是Java的Native方法通过方法指针来与JNI进行关联的,如果Native方法知道它在JNI中对应的方法指针,就可以避免上述的缺点,这就是动态注册。...动态注册 JNI中有一种结构用来记录Java的Native方法和JNI方法的关联关系,它就是JNINativeMethod,它在jni.h中被定义: ?...系统的MediaRecorder采用的就是动态注册,我们来查看它的JNI层是怎么做的。...关于动态注册就讲到这里,更多深入JNI的知识请见本系列后续的文章。 参考资料 《深入理解Android卷I》
JNI_OnLoad 函数原型 : Java 类中调用 System.loadLibrary(“native-lib”) 代码时 , 调用 JNI_OnLoad 方法 ; ① jni.h 中有该函数的声明...JNI_OnLoad 方法常用操作 : ① 获取 JavaVM 对象 ; ② 动态注册 JNI 方法 ; III . 被注册的本地 C/C++ 方法参数 ---- 1 ....; // C/C++ 中的 Native 函数签名 } JNINativeMethod; 2 ....JavaVM 获取 JNIEnv ( GetEnv ) ---- 函数原型 : 从 Java 虚拟机 ( JavaVM ) 中获取 JNI 运行环境 ( JNIEnv ) ; ① 参数说明 : void...函数原型 : 通过该 RegisterNatives 方法注册 JNI 方法 ; 参数 : jclass clazz : 要注册方法所在的 Java 类 const JNINativeMethod* methods
【Android】JNI静态与动态注册介绍 JNI的两种注册机制:静态注册和动态注册....方式: 静态注册 动态注册:需要提供Java中Native方法的方法签名和Native层中对应的实现函数。...动态注册 动态注册相对于静态注册,优点是不再根据特定路径查找函数的实现,带来两个好处: 没有了冗杂的函数名,适用于大型项目开发。...由于不再根据Native函数查找对应的JNI层函数,所以首次调用速度比静态注册快。 开发者需要自行提供Java层和C/C++层中的映射关系。...一种可行的方法是基于JNI重载JNI_OnLoad(),在其中对函数进行动态注册。
背景 面试NDK开发的时候,经常碰到一个问题:如何在jni中注册native函数,有几种注册方式?...答案:native方法的注册分为静态注册和动态注册 静态注册 静态注册的原理 原理:根据函数名来建立 java 方法与 JNI 函数的一一对应关系 实现流程 1.编写带有native声明的方法的java...动态注册的原理 原理:利用 RegisterNatives 方法来注册 java 方法与 JNI 函数的一一对应关系 实现流程 利用结构体 JNINativeMethod 数组记录 java 方法与...JNI 函数的对应关系; 实现 JNI_OnLoad 方法,在加载动态库后,执行动态注册; 调用 FindClass 方法,获取 java 对象; 调用 RegisterNatives 方法,传入 java...,用来指向 jni 函数 区别: 静态注册 优点: 理解和使用方式简单, 属于傻瓜式操作, 使用相关工具按流程操作就行, 出错率低 缺点: 当需要更改类名,包名或者方法时, 需要按照之前方法重新生成头文件
前言 在上一篇文章中,我们提到了注册 JNI 函数(建立 Java native 方法和 JNI 函数的映射关系)有两种方式:静态注册和动态注册。...静态注册 JNI 函数 1.1 静态注册使用方法 静态注册采用的是基于「约定」的命名规则,通过 javah 可以自动生成 native 方法对应的函数声明(IDE 会智能生成,不需要手动执行命令)。...因为 C 语言是没有函数重载的,无法根据参数来区分函数重载,所以才需要拼接后缀来消除重载。 1.2 静态注册原理分析 现在,我们来分析下静态注册匹配 JNI 函数的执行过程。...动态注册 JNI 函数 静态注册是在首次调用 Java native 方法时搜索对应的 JNI 函数,而动态注册则是提前手动建立映射关系,并且不需要遵守静态注册的 JNI 函数命名规则。...注册 JNI 函数的时机 总结一下注册 JNI 函数的时机,主要分为 3 种: 注册时机 注册方式 描述 1、在第一次调用该 native 方法时 静态注册 虚拟机会在 JNI 函数库中搜索函数指针并记录下来
这就是静态注册 动态注册:上面类似一张静态表,但是如果每个JNI的方法与Java的代码有个映射表,只要将这张表告诉JVM,那就可以找到对应的C++方法了 静态注册 对于静态注册,JNI的方法命名规则为:...动态注册 动态注册的关键字是两个: JNI_OnLoad()方法,这个是载入Jni库后调用的第一个方法,在这里可以将方法对应表注册给JNI环境 JNINativeMethod结构,这个结构是将jni层的方法映射到...层的方法名 signature:Java层的方法签名 fnPtr:JNI层的函数指针 比如上面的例子使用动态注册的实现如下: #include #include jstring...静态注册,每次使用native方法时,都要去寻找;而动态注册,由于有张表的存在,因此查找效率高。 编译 上面不管是静态注册方法,还是动态注册方法,都需要将cpp文件编译成平台所需要的库。...总结 上面主要是我自己从使用NDK开发中体会到的需要掌握的东西,最主要是静态注册与动态注册的实现。后面会介绍Java和JNI层如何互相作用,敬请期待。
在上一节《C++11 JNI开发中RAII的应用(一)》中我们已经有了一些基本的RAII封装工具,本节就简单了,就是根据需要把一些常用的JNIEnv函数封装成更方便使用的模板函数。...raii_NewGlobalRef raii_NewGlobalRef函数顾名思义,就是封装JNIEnv::NewGlobalRef,将一个本地引用的jobject转为全局引用封装在raii_var中。...{getJNIEnv()->DeleteGlobalRef(gref);}); } 在调用时,如果不指定T的类型,则返回的raii_var类中的类型默认为jobject,否则 下面所有的模板函数都是这个用法...obj,methodID,std::forward(args)...); } raii_NewObject raii_NewObject封装JNIEnv::NewObject有5个重载函数...java字节数组byte[]的C++字节数组 static auto raii_GetByteArrayElements(jbyteArray bytes, jint release_mode = JNI_ABORT
通过JNI实现一个Hello world。 1. 在Java类中声明native方法,NativeTest.java。...StdAfx.cpp,会在工程所在目录debug文件夹下生成native.pch文件,这个文件在编译native.cpp的时候需要用到;然后在Header Files中引入com_ghsau_NativeTest.h、jni.h...(com_ghsau_NativeTest.h需要,在jdk安装目录include下)、jni_md.h(jni.h需要,在include/win32下);最后编辑com_ghsau_NativeTest.h...、native.cpp,编辑后代码如下: com_ghsau_NativeTest.h /* 将修改为"jni.h" */ #include "jni.h" /* Header...以上就是实现JNI的一套过程。
什么是JNI java native interface java本地接口 c/c++与java之间相互调用的桥梁 为什么要学JNI java运行在虚拟机上,调用驱动需要jni来扩展他的能力 java解释型语言...,c/c++执行效率比java快,通过jni把耗时操作放到c/c++提高运行效率 java代码编译成的.class文件安全性较差,可以通过jni把重要的业务逻辑放到c/c++编译后是汇编语言,反编译难度大...c历史悠久,1972年c 通过jni可以调用优秀的c开源类库 怎么用JNI java c/c++能看懂 会调用 jni开发流程 NDK native develop kit
注册进去了。怎么做的呢? 控制器: 视图: 即可。
JNI 线程创建 II . 线程执行函数 III . 线程方法获取 Java 对象 IV . 线程方法获取 JNIEnv V . JNI 线程 完整代码示例 I . JNI 线程创建 ---- 1....线程执行函数 ---- 1. 线程执行函数的要求 : C++ 中规定线程执行函数的函数指针类型是 void *(PTW32_CDECL *start) (void *) ; 2....代表一个线程的句柄 pthread_t pid; //创建线程并执行 pthread_create( &pid , 0 , threadRun, 0 ); } //下面的代码是动态注册内容...动态注册方法 //获取 JNIEnv 指针 JNIEnv *env = nullptr; int registerResult = vm->GetEnv( (void **)...= JNI_OK){ return -1; } //进行动态注册 jclass jclazz = env->FindClass(className);
JNI 的一般开发流程 1 定义好本地的 native 方法 2 javah 命令生成 .h 头文件 3 拷贝 xxx.h、jni_md.h、jni.h 到 VS 的工程目录并添加依赖进来 4 实现我们头文件中的...Included_com_darren_ndk12_NdkSimple #ifdef __cplusplus // 相当于 if 语句 c++ // 不管是 c 还是 c++ 统一都是采用 c 的编译方式,因为在c里面是不允许函数重载的...: 这个是 c 和 java 相互调用的桥梁,所有 function 搞清 // jobject: java传递下来的对象,就是本项目中 JniSimple java 对象 // jclass: 静态函数的时候...#endif struct JNIEnv_ { const struct JNINativeInterface_ *functions; // .... } 在实现的函数里面...JNIEnv * 其实已经是一个二级指针了,所以 -> 调用的情况下必须是一级指针 *取值 return (*env)->NewStringUTF(env,"940223"); } 所以为什么在c里面调用函数需要用
JNI基本使用-静态注册 ?...JNI基本使用-动态注册 ?...动态注册对比静态注册 1.静态注册 编写不方便,JNI 方法名字必须遵循规则且名字很长 程序运行效率低,因为初次调用native函数时需要根据根据函数名在JNI层中搜索对应的本地函数,然后建立对应关系...,这个过程比较耗时 2.动态注册 流程更加清晰可控 效率更高 JNI基本使用-将Native层的类和Java的类绑定 ?...MainActivity的属性myClass env->SetObjectField(object, jfield, myclass); } 总结 1.Java层调用Native层的方法,只能通过动态注册或者静态注册的
领取专属 10元无门槛券
手把手带您无忧上云