JNI简介
什么是JNI
java本地开发接口(Java native interface)
我自己的理解,JNI就是java和c语言通信的编程规范,按照JNI编程规范,可以在java中调用c代码,可以在c中回调java代码,可以在java和c中
传递变量,你按照规范写好的代码,只要使用NDK编译工具编译出so/a文件,java就可以使用了。
为什么用jni
1 JNI扩展了java 虚拟机的能力, 驱动开发 (wifi-hotspot) 2.3 无线热点共享.
Java语言不能进行驱动的开发 , 驱动 就是直接操作硬件
2 Native code效率高,数学运算,实时渲染的游戏上,音视频处理 (极品飞车,opengl,ffmpeg)
Java语言自动回收内存 基于二级链表算法 程序员没法控制
C语言 手动回收 回收内存程序员可以控制的
3 复用代码 (文件压缩,人脸识别opencv,7zip)
Java 95 98年 2000
C 1970年 产生大量可以复制的代码
4 特殊的业务场景
车载系统
JNI开发
什么是NDK
Native developer kits;本地开发工具链,将你按照JNI规范写出来的代码交叉编译成so或a库
为什么使用NDK
提供了一个交叉编译的工具链
C语言不是跨平台的语言 在windows平台下写好的c代码 想让他在linux系统下运行
Windows 平台下的函数库 是.dll linux下的是 .so
1 把windows平台下写好的c代码 打包编译生成 linux下可以用的函数库
2 电脑cpu x86架构的cpu 手机 arme架构的cpu 需要把电脑编写的c代码 打包成手机可以运行的函数库
怎么用ndk
第一步 下载
第二步 把下载的ndk 解压到非中文目录下
Ndk目录结构
Build NDK搭建环境
Docs ndk开发的文档
Platforms ndk支持的平台
Arm 平台 英国arm公司设计出来 靠专利赚钱市场占有率非常高功耗比较低
Mips cpu架构 龙芯 cos copy other system
x86 intel公司 没有明显的优势 k900
Samples 提供了示例代码
Sources ndk是开源, ndk的源码
Tests 测试的工具链
Toolchains 提供了交叉编译的工具链
ndk-build.cmd 批处理指令 ,交叉编译
证明ndk搭建成功了
把ndk-build 配置到环境变量中
Jni规范协议
C:\android-ndk-r9b-windows-x86\android-ndk-r9b\platforms\android-9\arch-arm\usr\include\jni.h(你自己ndk目录下)
Java语言开源但是java的虚拟机不是开源的
dlvk
RunTime 运行效率 要比之前的高 ,程序安装的时间慢
typedef struct {
const char* name;
const char* signature;
void* fnPtr;
} JNINativeMethod;
描述一个方法
给结构体的指针conststruct JNINativeInterface* 起了一个别名 叫做 JNIEnv
typedef const struct JNINativeInterface*JNIEnv;
JNINativeInterface 规定了java语言中 最基本的方法
JNI开发的步骤
步骤1
步骤2
在工程目录下 创建jni文件夹,里面创建一个Hello.c的文件
步骤3
写c代码
步骤4
交叉编译了,
把c代码 交叉编译成手机可以运行的函数库
进入到jni目录下 创建一个 Android.mk脚本文件
来到控制台,进入工程目录 执行ndk-build指令
Armeabi
arme 平台下 abi application binary interface 在这个文件夹下的函数库 只能部署到arme平台下
Obj 交叉编译的中间文件
Hello.c ->Hello.o-> Hello.o.d->.so
步骤5
步骤6
直接使用方法
JNI 简单的开发步骤
1 创建本地方法
// 步骤1 创建native方法
public nativeString helloFromC();
2 配置ndk变量 (只需要1次)
3 右键点击工程 Android Tools -> addNative Support 需要关联源码否则可能会报错
4 把cpp代码改成c代码 (非必要)
Android.mk文件中 记得也要修改
删除obj目录
5 javah指令 自动生成 c函数的标头文件
1.7 进入到工程目录 进入到 src目录 javah + native方法所在类的全类名
1.6 进入到工程目录 进入到bin\classes目录 javah + native方法所在类的全类名
6 关联源码为了让代码有提示
右键点击工程
C:\android-ndk-r9b-windows-x86\android-ndk-r9b\platforms\android-9\arch-arm\usr\include
7 切换到c/c++ 视图 点击上面的锤子 会自动交叉编译
8 引入函数库
9 使用方法
Android.mk文件
Ndk常见的错误
错误1
01-25 01:40:37.099: E/AndroidRuntime(1616):Caused by: java.lang.UnsatisfiedLinkError: Couldn't load hello: findLibraryreturned null
原因 部署错了平台
01-25 02:53:39.795: E/AndroidRuntime(6266):java.lang.UnsatisfiedLinkError: hello_From_C
原因1 可能没有引入函数库
原因2 java方法和c方法对应不上
错误2 Android.mk文件有错误
不要在android.mk文件出现 全角符号
错误3 c文件有编译异常
错误4
c语言有运行时异常
Logcat 输出红色日志 ,打印一堆debug信息
早期jni开发
早期的ndk版本 不兼容windows
借助 Cygwin 在windows平台 模拟一个linux系统的环境
跨平台
在jni/Application.mk
APP_ABI := x86 兼容x86 cpu
解决警告
APP_PLATFORM := android-8