JNI技术的使用方法
申请博客好长时间然而却没有时间去总结自己的学习心得,今天忽然发现以前学的好多东西都忘记了,开始了自己的总结和复习,以后也会不间断的更新;闲话不说,进入正题。
JNI既然作为一门技术,在学习一门技术的时候,首先要明白的是:
1、什么是JNI技术:jni是一种协议,这个协议用来沟通java代码和外部的本地代码(c/c++),通过这个协议,java代码就可以调用外部的c++代码。
2、为什么要使用jni技术:可以复用很多的c/c++代码,例如:ffmeng多媒体播放器,opencv图形识别的引擎,7-zip压缩,opencore框架(用于视频播放)等等。另外可以提高程序的效率:java代码跨平台,不直接操作硬件,虚拟机解释执行,实现垃圾回收机制。art在安装应用程序的时候,将apk里面的dex翻译成机器码,造成apk体积变化很多;而c代码直接操作硬件,程序猿可以手动的释放代码。c代码反编译困难,因为反编译出来的是汇编语言;而java代码饭编译容易,很容易看懂。
3、使用jni技术需要你掌握什么样的能力:看懂c代码;懂流程,熟悉jni的规范;熟练使用ndk工具。
JNI的具体使用步骤是:(个人总结了八个步骤)
(1)、在java本地代码中声明一个native方法:例如:public native String helloJni();
(2)、在eclipse中创建一个文件夹,名称必须命名为jni;
(3)、在jni这个文件夹下创建一个.c文件,按照c代码的规范来写,但是方法的命名有特殊的要求,例如我们现在需要从c代码中返回一个java的String类型的字符串;具体的写法:jstring Java_com_example_my_QQConnection_hello(JNIEnv* env, jobject obj){
char* str = "hello java";
//在jni规范里面 在jni环境的结构体中;
//转换成java字符串;
//jstring (*NewStringUTF)(JNIEnv*,const char*);
//*env指的是java虚拟机的地址;而这个地址有是结构体的指针;因此要拿到结构体的地址就必须(*(*env))这个指的是结构体的地址,也就是结构体;此时就可以条用结构体的方法。
return (*(*env)).NewStringUTF(env,str);
}4、ndk-build.cmd指令编译c代码(注意:如果不配置Android.mk文件的话就会报错);
5、配置Android.mk文件;
#指定编译的文件夹 指定当前的文件目录;
LOCAL_PATH := $(call_my-dir)
#编译器会产生很多的中间变量,临时变量,最好清空所有的中间变量。
include $(CLEAN_VARS)
#编译出模块的名称;
LOCAL_MODULE : = hello
#编译源代码的名称;
LOCAL_SRC_FILES : = hello.c
#编译一个动态库;
#动态库 文件名.so 包含函数,不包含函数运行的依赖,体积小,运行的时候,去操作细听寻找需要的额API.
includes $(BUILD_SHARE_LIBRARY)
6、编译过后,自动生成一个.so的动态链接库;
7、在java代码中,把动态链接库加载到jvm虚拟机中加入一个静态代码块,规则如下;
static{
System.loadLibrary("库文件名,不加前缀和后缀");
}
8、像调用java代码一样,调用native方法;
上面的这个方法,是java代码调用c代码;用c代码调用java代码会在后续的更新中写出来。

浙公网安备 33010602011771号