一、什么是JNI 1.java本地开放接口(java native interface) 2.作用相当于一个桥梁,是java与C之间调用的一种协议 3.通过JNI就可以让java调用C或C++代码,并且可以让C调java代码 4.当java中的某个方法类似涉及大量的数学运算时,java的效率就不如C高了,例如压缩跟解码处理,大多是用C来写的,都很消耗性能(直播、视频处理、图片处理都是用C) Android系统图:
二、为什么要用JNI 1.native coder执行效率高:大量的运算(极品飞车)、万能解码(FFmpeg)、Opengl(3D渲染) 代码复用:ffmpe,onencv(人脸识别库),7-zip(开源压缩软件) 三、怎么使用JNI ndk : native develop kits 将C文件编译成so文件 so文件的引用:http://blog.csdn.net/QQ_32239767/article/details/54645661 用处范例:增量升级 四、C语言基础 1.这里用Dev-c来写C程序,感觉起来不如VC6.0用着顺手 2.java基本数据类型与C语言的不同点 ⑴java中char类型占2个字节,C语言中长度占1个字节 ⑵java中long类型占8个字节,C语言中长度占4个字节 ⑶C语言中没有boolean类型,C语言中0表示false,非0表示true C语言中没有bool类型,用特殊色彩标记关键字的功能是编辑器的功能而非编译器的功能,因为C++有bool类型,因此bool会被编辑器标亮,但是C语言编译器是不会认识这个关键字的。Bool是C++里的类型bool是布尔型变量,也就是逻辑型变量的定义符,只有一个字节。 ⑷C语言中没有byte ⑸unsigned 无符号 0~255 signed 有符号 -128~127 ⑹goto在java中只是保留并没有实际用处 ⑺C语言中没有字符串,可以用字符数组表示 ⑻C语言中有指针,指针就是内存地址 3.system(“pause”);//保持显示的状态 4.#include
以上代码输出结果为6,但是可以把起始值改掉,例如:
#include<stdio.h>#include<stdlib.h>/**枚举的值递增 默认首元素的值是0 */enum WeekDay { Monday=4,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday};main() { enum WeekDay day = Sunday; printf("%d/n",day); system("pause");}以上结果输出为10 7.别名typedef:把很长的名字用简写代替
#include <stdio.h> #include <stdlib.h>typedef int i;typedef long l;typedef float f;main() { i m = 10; l n = 123123123; f s = 3.1415; printf("%d/n", m); printf("%ld/n", n); printf("%f/n", s); system("pause"); }8.结构体
#include<stdio.h>#include<stdlib.h>//定义结构struct student{ int age;//4个字节 float score;//4个字节 char sex; //1个字节 } ; main(){ //使用结构体 struct student stu = {18,98.9,'W'}; //结构体取值 printf("stu.age==%d/n",stu.age); printf("stu.score==%.1f/n",stu.score); printf("stu.sex==%c/n",stu.sex); //结构体赋值 stu.age = 20; stu.score = 100; stu.sex = 'M'; printf("stu.age==%d/n",stu.age); printf("stu.score==%.1f/n",stu.score); printf("stu.sex==%c/n",stu.sex); //结构体的长度 printf("struct student长度==%d/n",sizeof(struct student)); system("pause"); }9.联合体
#include<stdio.h>#include<stdlib.h>//定义一个联合体,特点,所有的字段都是使用同一块内存空间; union Mix { long i; //4个字节 int k; //4个字节 char ii;//1个字节 };main() { printf("mix:%d/n",sizeof(union Mix)); //实验 union Mix m; m.k = 123; m.i = 100; printf("m.i=%d/n",m.i); printf("m.k=%d/n",m.k); system("pause");}这里结构体长度大小的求解时要特别注意,时刻记住有个倍数的问题 10.在结构体中(*stuPoint).age 等价于 stuPoint->age 11.#define: ①在用#define定义常量时,行尾一般不能有分号,除非特意这样做 ②define前边的#标志着define是一个预处理命令而不是C语句 ③符号常量名最好使用大写字符来命名 五、Android Studio下的 NDK 环境配置 **注意:JNI是一个协议,NDK是Google提供的开发JNI的一个工具包 NDK(native develope kit):本地开发工具包 1.NDK随便找个目录放进去就行,但是目录路径中最好不要有中文或者空格 2.NDK各版本下载地址:http://tools.android-studio.org/ 3.配置环境变量path 4.让ndk与Android studio进行关联 ①在配置好ndk后local.properties中会自己显示ndk.dir=D:/adt-bundle-windows-x86_64-20140702/sdk/ndk-bundle ②在gradle.properties中添加android.useDeprecatedNdk=true//兼容老版本ndk
③编写代码 ④在app的build.gradle中添加
ndk{ moduleName "Hello" //so文件: lib+moduleName+.so abiFilters "armeabi", "armeabi-v7a", "x86" //cpu的类型 }
注:这个ndk代码块不写也可以,不过生成的.so文件的名字会是lib+项目名+.so,并且会把所有支持的CPU架构下的.so文件都编译出来,如果缺少你手机CPU架构的.so文件,程序会报错或者崩溃甚至是不能运行 5.NDK开发流程 ①在java里面写native代码 ②在main目录下创建jni目录写C代码–生成头文件 ③配置动态链接库的名称 ④加载动态链接库:针对不同CPU架构的手机它会编译成不同的.so文件 ⑤开始使用 6.Java类型对应的JNI别名
最后附几篇关于NDK、JNI的博客链接: 链接1:http://blog.csdn.net/Tongseng/article/details/53005123
新闻热点
疑难解答