详解Android JNI的基本使用(CMake)

详解Android JNI的基本使用(CMake),第1张

概述简介什么是JNIJNI的全称是JavaNativeInterface:Java本地开发接口,它提供了若干的API实现了Java和其他语言的通信(主要是C和C++),目的就是Java可以调用C或C++开发的函数,C或C++也能调用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”文件

笔者项目目录如下:

测试实例

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。

最终效果如下:

创建本地方法

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,然后进入到app\build\intermediates\classes\deBUG目录下。

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

效果如下:

 

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

/* DO NOT EDIT THIS file - it is machine generated */#include <jni.h>/* 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 __cplusplusextern "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 JNICALLJava_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.txtcmake_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”文件生成如下:


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

总结

以上是内存溢出为你收集整理的详解Android JNI的基本使用(CMake)全部内容,希望文章能够帮你解决详解Android JNI的基本使用(CMake)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1143258.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存