[关闭]
@Tyhj 2019-07-19T16:30:25.000000Z 字数 2021 阅读 1889

在已有Android项目中引入Jni

Android


在Android项目中使用Jni还是比较简单的,新建项目的时候选择Native C++就可以自动配置好Jni项目;但是一个已经存在的项目想要使用Jni就需要自己去写一些配置文件了;其实这些步骤都很简单,而且有助于理解整个Jni的实现过程;

编写Cmake文件

Android studio是通过 CMake 和 NDK 将 C/C++ 代码编译成底层的so库,然后再配合 Gradle 的编译将库打包到 APK 中,所以首先就需要编写CMakeLists.txt文件;

常用方法

  • add_library 指定要编译的库,并将所有的 .c 或 .cpp 文件包含指定。
  • include_directories 将头文件添加到搜索路径中
  • set_target_properties 设置库的一些属性
  • target_link_libraries 将库与其他库相关联

文件路径

src/main/路径下新建jni文件夹,在文件夹下面新建CMakeLists.txt文件

文件内容

  1. # 设置cmake的最低版本
  2. cmake_minimum_required(VERSION 3.4.1)
  3. # 设置生成的so库的信息
  4. add_library(
  5. #生成的so库的名字
  6. jnitest
  7. # 生成的so库的类型,类型分为两种:
  8. # STATIC:静态库,为目标文件的归档文件
  9. # SHARED:动态库,会被动态链接,在运行时被加载
  10. SHARED
  11. # 设置源文件的位置,可以是很多个源文件,都需要添加进去
  12. jnitest.cpp)
  13. # 从系统里查找依赖库,可添加多个
  14. find_library(
  15. log-lib
  16. # liblog.so库指定的名称为 log,libjnitest.so的名称为jnitest
  17. log)
  18. # 配置目标库的链接,即相互依赖关系
  19. target_link_libraries(
  20. # 目标库(最终生成的库)
  21. jnitest
  22. # 需要依赖的log库,一般情况下,如果依赖的是系统中的库,需要加${}进行引用
  23. # 如果是第三方库,可以直接引用
  24. # 每行引用一个库
  25. ${log-lib})

我在里面设置了源文件的路径为jnitest.cpp,所以在同一目录下新建这个c++文件,文件内容如下:

  1. #include<jni.h>

Gradle中配置cmake文件

需要在Gradle中配置cmake文件,点击File/Link C++ Project with Gradle,选择刚才创建的cmake文件,然后会在app的build.gradle文件的Android节点里面添加如下代码;自己去添加也是一样的,目的是配置构建脚本路径

  1. externalNativeBuild {
  2. cmake {
  3. path file('src/main/jni/CMakeLists.txt')
  4. }
  5. }

新建native方法

随便一个Java类中加载jnitest,调用一下里面的方法,现在里面没有方法,我们可以先在Java中申明,会提示方法不存在,可以自动在C++文件中生成相应方法;

  1. static {
  2. System.loadLibrary("jnitest");
  3. }
  4. public native String helloWorld();

使用C++第一次好像会自动生成一个C文件,没法自动生成方法,自己在C++里面自己写一下就好了

  1. #include<jni.h>
  2. #include <string>
  3. extern "C"
  4. JNIEXPORT jstring JNICALL
  5. Java_com_hikvision_testapp_MainActivity_helloWorld(JNIEnv *env, jobject instance) {
  6. // TODO
  7. std::string hello = "Hello from C++";
  8. return env->NewStringUTF(hello.c_str());
  9. }

然后Java中调用这个native方法就是调用了C++的代码了;build一下,就会在如下目录生成so库
![image_1dg4fudg41kjba831apeb8c1khv9.png-28.5kB][1]

也可以在app的build.gradle的Android节点下的defaultConfig节点下面添加如下代码,设置编译的出的so库支持的cup架构

  1. externalNativeBuild{
  2. cmake{
  3. abiFilters "armeabi-v7a","x86"
  4. }
  5. }

so库的使用

可以在其他项目中使用这些so库,只需要在src/main/文件夹下面新建jniLibs文件夹,把生成的so库包括文件夹复制到里面;
使用的时候和刚才的使用是一样的,加载库,创建native方法即可;但是需要注意是是,刚才在C++文件里面是静态注册方法,能通过这个映射方式找到C++中的方法,使用者的包的路径和native方法也必须和之前编译的项目路径一致才可以;感觉先根据so库创建一个library,里面用Java去实现so库的功能,对外提供接口是不错的方法

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注