JNI And NDK学习笔记

JNI And NDK学习笔记

JNI

1 什么是JNI

即Java Native Interface :提供了Java与C语言相互调用的接口,能利用c语言程序高效的优势,便于实现高性能的程序;

2 Java 中编写JNI的步骤

  1. 创建Java工程,在main目录下创建cpp目录
  2. 在Java文件中编写native 方法,再在命令行使用javah [带native关键字的类的全名路径],将生成的.h文件拷贝到cpp目录下
  3. 将jni开发常用的jni.h 以及jni_md.h文件加入项目路径;
  4. 实现.h头文件中声明的jni方法
  5. 配置jni工程生成dll的配置,配置管理器中选定平台为arm(注意MinGw的版本要为64位),否则会报ERROR:生成的dll位数不兼容;
  6. 生成dll,并将生成的dll文件路径放入环境变量,使用system.loadLibrary加载dll,重启eclipse(这样才能识别更改的环境变量)
  7. 在Java类中调用native方法

3 JNI 的几种关键结构体

​ JNIEnv介绍

​ JNI的环境参数结构体

4 属性与方法访问

1. Java 调用Jni 返回String
(*env)->GetStringUTF(env,jobj);
2. JNI访问Java变量的值
//获取java对象的签名ID
jfiledID fid = (*env)->GetFiledID(env,cls,"key", "Ljava/lang/String;");
//获取Java变量的对象域
(*env)->GetObjectField(env,jobj,fid);
//获取新的值x
//将x设置到对应的java变量并返回
(*env)->setObjectField(env,jobj,fid,x);
return x;

5 JNI 通知GC释放对象引用

1. 函数名 (*env)->deleteLocalRef(jobj)

​ JNI通过deletelocalRef()可以完成对无用的较大对象引用的释放;

6

NDK基础知识

准备工作

在window上,开发NDK需安装如下软件:

  • cywin - make( make util for gun)
  • android ndk
  • apache ant
  • jdk (above 1.5)
  • android studio

几个重要的NDK包

1. Build System
1.1 Build System 的功能
  • 生成动态库(Shared Library)

  • 生成静态库(Static Library)

  • 提供公共模块(通过动态库的方式)

  • 使用prebuilt libraries

  • 生成标准执行文件

1.2 Start build system with sample
  1. github上下载android-ndk-sample源码
  2. 在android studio 中import 相应的ndk sample
  3. 更改ndk版本为合适的版本,若本地无合适版本则到官网下载
  4. 点击代码Editor-编辑器上的try again按钮,编译ndk项目
1.3 get start a jni sample
  1. 编写CMakeLists.txt ,指明cmake版本,源文件,编译的共享库,依赖的动态库等等;
  2. 编写ndk代码,在cpp路径下编写.cpp文件代码,无需jni头文件定义
  3. 编写的cpp文件中分两块代码区,用extern “C”{}包括的代码块属于JNI代码,对于静态Java方法,其对应的JNI方法第二个参数是jclass,对于实例java方法,第二个参数是jobject
1.3 java类型与jni类型映射表
  1. 基本类型映射表

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3TLXBVyi-1654609807328)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20210411095739063.png)]

  2. 引用类型映射表

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mNLIR2t8-1654609807330)(C:\Users\asus\AppData\Roaming\Typora\typora-user-images\image-20210411095943431.png)]

宏方法的定义

​ 作用:

  1. #define call(Name) test##Name()
  2. 动态替换test方法的后缀,形成不同的testXXX()函数,前提是testXXX()已经定义;

C语言中调用Java中的函数解决JNI中文字符编码的问题

​ 原因:某些C语言中的API调用繁琐,用Java中的API会更为便捷;

​ 步骤:

1. 获取对应类名的签名,通过env->findClass 获取对应的jclass ;
2. 获取对应类的某个方法签名, 命令:javap -s -m 方法名
3. 将c++中要返回的字符串设置成env中的字节流,再获取编码名-charsetName;
4.  通过jni调用java方法来返回编码好的中文字符;

其他 一些常见的应用

  1. 文件加解密 --异或机制的应用

    原理:将文件按字符读出,并将每个字符与密码位异或

    异或的时候要注意是用的txt作为加解密的测试文件类型,其他类型的文件(如PNG)可能要做额外处理

  2. JNI 实现本地文件拆分

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值