java native 接口_简介什么是JNIJNI的全称是Java Native Interface:Java本地开发接口,它提供了若干的API实现了Java和其他语言的通信(主要...

简介

什么是JNI

JNI的全称是Java Native Interface:Java本地开发接口,它提供了若干的API实现了Java和其他语言的通信(主要是C和C++),目的就是Java可以调用C或C++开发的函数,C或C++也能调用Java的方法。这样有很多有点,其一就是效率,C/C++是本地语言,比java更高效;其二就是可以复用已经存在的C/C++代码;其三是Java反编译比C语言容易,一般加密算法都是用C语言编写,不容易被反编译。

什么是NDK和CMake

NDK全称是Native Development Kit,NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和Java应用一起打包成apk。NDK集成了交叉编译器,并提供了相应的mk文件隔离CPU、平台、ABI等差异,开发人员只需要简单修改mk文件(指出“哪些文件需要编译”、“编译特性要求”等),就可以创建出so。

CMake是一个比make更高级的编译配置工具,它可以根据不同平台、不同的编译器,生成相应的Makefile或者vcproj项目。

通过编写CMakeLists.txt,可以控制生成的Makefile,从而控制编译过程。CMake自动生成的Makefile不仅可以通过make命令构建项目生成目标文件,还支持安装(make install)、测试安装的程序是否能正确执行(make test,或者ctest)、生成当前平台的安装包(make package)、生成源码包(make package_source)、产生Dashboard显示数据并上传等高级功能,只要在CMakeLists.txt中简单配置,就可以完成很多复杂的功能,包括写测试用例。如果有嵌套目录,子目录下可以有自己的CMakeLists.txt。

使用流程

1、在java文件中创建本地方法

2、build项目后自动生成“.h”文件

3、创建.cpp文件,实现.h文件中的方法

4、配置Cmake文件,生成“.so”文件

笔者项目目录如下:

5de2b077208c690d95fc828664d8fc1b.png

测试实例

public class MyJNI {

private static final String TAG=MyJNI.class.getName();

@Test

public void test(){

JNITest jniTest=new JNITest();

Log.d(TAG,jniTest.nativeCalculate(2)+"");

}

}

1、调用native方法nativeCalculate,传入参数2。

1、获取java对象number,初始值为0。

2、调用java方法javajavaCalculate,传入number值,获得返回值10。

3、将返回值加上参数2,返回,获得12。

最终效果如下:

c1183c3a18cee5ace022328a6e4653b0.png

创建本地方法

public class JNITest {

private int number = 0;

public int javaCalculate(int num){

number=num+10;

return number;

}

public native int nativeCalculate(int num);

static {

System.loadLibrary("jni_test");

}

}

自动生成“.h文件”

首先make Project,然后进入到appbuildintermediatesclassesdebug目录下。

24062502a27b5df9340cae65799daf3a.png

在终端输入命令javah com.example.xujiajia_sx.jnitest.JNITest(即带有native方法的类)

效果如下:

4a7bf7129c12fa918ef3c3846ac0c4a2.png

自动生成的“.h”文件如下,可以根据自己要求对其重命名或者增减内容。

/* DO NOT EDIT THIS FILE - it is machine generated */

#include

/* Header for class com_example_xujiajia_sx_jnitest_JNITest */

#ifndef _Included_com_example_xujiajia_sx_jnitest_JNITest

#define _Included_com_example_xujiajia_sx_jnitest_JNITest

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: com_example_xujiajia_sx_jnitest_JNITest

* Method: nativeCalculate

* Signature: (I)I

*/

JNIEXPORT jint JNICALL Java_com_example_xujiajia_1sx_jnitest_JNITest_nativeCalculate

(JNIEnv *, jobject, jint);

#ifdef __cplusplus

}

#endif

#endif

创建cpp文件实现native方法

笔者cpp文件如下:

#include "jni_test.h"

JNIEXPORT jint JNICALL

Java_com_example_xujiajia_1sx_jnitest_JNITest_nativeCalculate(JNIEnv *env, jobject obj,jint num) {

//获取obj中对象的class对象

jclass clazz = env->GetObjectClass(obj);

//获取clazz中的number字段的id

jfieldID id_number = env->GetFieldID(clazz, "number", "I");

jmethodID id_java_calculate=env->GetMethodID(clazz, "javaCalculate", "(I)I");

//次获取java中number的值

jint number = env->GetIntField(obj, id_number);

jint result=env->CallIntMethod(obj,id_java_calculate,number);

env->SetIntField(obj,id_number,result+num);

//再次获取java中number的值并返回

return env->GetIntField(obj, id_number);

}

主要逻辑是获取到java中number的值,然后调用javaCalculate()方法,接着再加上这个native方法的参数num。

设置Cmake文件,生成”.so”文件

首先,在build.gradle中添加Cmake配置:

android {

...

defaultConfig {

...

externalNativeBuild {

cmake {

cppFlags ""

//生成多个版本的so文件

abiFilters 'armeabi','armeabi-v7a','x86'

}

}

}

buildTypes {

...

}

externalNativeBuild {

cmake {

path "CMakeLists.txt"

}

}

}

编写Cmake文件:

#CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

add_library( # Sets the name of the library.

jni_test

# Sets the library as a shared library.

SHARED

# Provides a relative path to your source file(s).

src/main/jni/jni_test.cpp)

include_directories(src/main/jni/)

find_library( # Sets the name of the path variable.

log-lib

# Specifies the name of the NDK library that

# you want CMake to locate.

log )

target_link_libraries( # Specifies the target library.

# 制定目标库.

jni_test

# Links the target library to the log library

# included in the NDK.

${log-lib} )

配置完cmake,rebuild项目,即可以运行test。“.so”文件生成如下:

913a9e654a2f2711e9d1a328540e696c.png

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值