一 JNI理解
JNI: java native interface
使用环境:
- java api 不能满足我们程序的需要的时候。
- 算法计算,图像渲染 效率要求非常高,
- 当需要访问一些已有的本地库
NDK:
工具的集合。帮助开放者快速开放C/C++ 动态库的工具。
jni 是java 语法的概念 ,ndk是android 的概念
二 JNI简单调用
1 编写native 方法
Eclipse或AS中新建项目,定义一个java类
public class JniMain {
public native static String getStringFromC();
}
2 编译生成.h头文件
命令行进入到项目的根目录下
命令:
javah -classpath . -jni 包名.JniMain
生产的头文件
3. 复制.h 头文件到cpp 工程
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class JniMain */
#ifndef _Included_JniMain
#define _Included_JniMain
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JniMain
* Method: getStringFromC
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_JniMain_getStringFromC
(JNIEnv *, jclass);
/*
* Class: JniMain
* Method: getStringFromC2
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_JniMain_getStringFromC2
(JNIEnv *, jobject);
/*
* Class: JniMain
* Method: accessField
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_JniMain_accessField
(JNIEnv *, jobject);
/*
* Class: JniMain
* Method: accessStaticFiel
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_JniMain_accessStaticFiel
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
4. 复制jni.h 和jni_md.h(在jdk目录搜索)
改尖括号为双引号
错误:无法打开源文件jni.h
解决方法:引入jni.h的全路径
#include “C:\Users\PF0ZYBAJ\source\repos\Lsn6\Lsn6\jni.h”
5. 实现.h 头文件中的声明函数
#include "stdafx.h"
#include <stdio.h>
#include "JniMain.h"
#include <string.h>
// 静态方法 jclass
JNIEXPORT jstring JNICALL Java_com_bpj_ndk_JniMain_getStringFromC
(JNIEnv * env, jclass jclz) {
return (*env)->NewStringUTF(env, "C string");
}
// 非静态方法 jobject
JNIEXPORT jstring JNICALL Java_com_bpj_ndk_JniMain_getStringFromC2
(JNIEnv * env, jobject jobj) {
return (*env)->NewStringUTF(env, "C string2");
}
注意: 先要将所有的.h文件拷贝到C或CPP的.h文件夹路径,然后再资源管理器中添加现有项,而不是直接复制
6. 生成一个dll 动态库文件
工具栏Debug->x86->配置管理器-平台:x64
右键项目名->属性->常规->项目默认值-> 配置类型->动态库(.dll)
注意: 64位的平台对应64的环境,不然加载后运行失败
7. 在java中加载动态库
拷贝dll文件到项目根目录下
注意:
- 拷贝到根目录
- 没有.dll 后缀名
8. 触发native函数
静态库和动态库
都是函数库。
静态库:.a
动态库: .dll/.so
JNIEnv 是什么?
C:
JNIEnv 结构体指针的别名
env 是二级指针
C++:
JNIEnv 是机构体的别名
env 是一级指针
每个native 函数,都至少有两个参数(JNIEnv * , jclass/jobject)
jclass: native 静态方法
jobject: native 非静态方法
三 JNI基本数据类型
-
基本类型
boolean jboolean
byte jbyte;
char jchar;
short jshort;
int jint;
long jlong;
float jfloat;
double jdouble; -
引用类型:
String jstring
Object jobject -
基本数据类型数组:
//type[] jTypeArray;
byte[] jByteArray;
四 Demo
lsn6_JNI的简单调用