当前位置:   article > 正文

Android Studio 中编译 JNI 代码_android studio 编译jni

android studio 编译jni

Android Studio 中编译 JNI 代码

经常需要实现一些 C,C++ 接口的功能模块,提供给 java 层调用。

那么就需要利用 JNI 写接口提供 java 的 native 调用。

必不可少的一步就是编译 JNI 代码。

需要的文件

  • (项目)
    • src
      • main
        • cpp
          • JNI 代码(依赖)
        • java
          • (接口类 class)
        • jniLibs
          • (ANDROID_ABI)
            • 依赖库文件
    • build.gradle
    • CMakeLists.txt
文件/目录说明
src/main/cpp/用于存放JNI源码(C、C++等),也有人喜欢更名为 jni/
src/main/java/JNI 接口的 java 调用
build.gradle配置 CMake 编译等参数
CMakeLists.txt用于设置 JNI 代码的编译方式

配置 build.gradle

android {
    ...
    defaultConfig {
        ...
        ndk {
            abiFilters "armeabi-v7a"
        }
    }

    externalNativeBuild {
        cmake {
            path "CMakeLists.txt"
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

ndk.abiFilters 是配置编译的CPU架构,会根据架构编译出不同架构的 .so 文件。

cmake 是配置 CMake 的编译规则文件的路径,如果和 build.gradle 同级就不需要增加目录,否则按与 build.gradle 文件的路径自行配置。

添加 JNI 源码

个人习惯问题,喜欢按功能模块把 JNI 源码分类:

cpp/{功能}/include/:存放头文件

cpp/{功能}/src/:存放源代码

cpp/:存放 JNI 接口代码

这是个人习惯问题,大家可以无视。

一些 arm 架构的 so 库,建议放在 src/main/jniLibs/{ANDROID_ABI}/ 下,因为对于动态 .so 库,程序运行时需要依赖。

示例 cpp 文件

添加 JNI 接口

在 JNI 中,需要自行根据添加 java native 的接口位置,添加 JNI 接口。

比如我想在:src/main/java/org/xxx/yyy/zzz/faceapi/FaceApiNative.java 中添加一个名为 JniJudgeHdr 的 native 接口。

    public native boolean JniJudgeHdr(byte[] bytes, int width, int height, int channels);

    static {
        System.loadLibrary("facehdr");
    }
  • 1
  • 2
  • 3
  • 4
  • 5

那么我们需要增加的 JNI 接口为:

JNIEXPORT jboolean JNICALL
Java_org_xxx_yyy_zzz_faceapi_FaceApiNative_JniJudgeHdr(
        JNIEnv* env, jobject /* this */
        , jbyteArray jbArr_image
        , jint rows
        , jint cols
        , jint channels
        ) {
    ...
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

基本的文件框架为:

#include <jni.h>
#include <android/log.h>

// #include "facehdr_jni.h" // 非必要
#include "judge_hdr/include/JudgeHdr.h" // 其它依赖的头文件

#ifdef __cplusplus
extern "C" {
#endif

JNIEXPORT jboolean JNICALL
Java_org_xxx_yyy_zzz_faceapi_FaceApiNative_JniJudgeHdr(
        JNIEnv* env, jobject /* this */
        , jbyteArray jbArr_image
        , jint rows
        , jint cols
        , jint channels
        ) {
    ...
}

#ifdef __cplusplus
}
#endif
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

同时如果 java 需要调用 JNI 接口,就需要设置加载对应的 JNI 库。(示例 System.loadLibrary 部分)

编译 CMake 规则

先上内容

cmake_minimum_required(VERSION 3.4.1)

# 编译后的 so 保存的位置
#set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})

# 头文件路径
include_directories(
            ${CMAKE_SOURCE_DIR}/src/main/cpp
            ${CMAKE_SOURCE_DIR}/src/main/cpp/judge_hdr/include
        )

file(GLOB FACE_HDR_SRC
                        ${CMAKE_SOURCE_DIR}/src/main/cpp/facehdr_jni.cpp
                        )

add_library(
             facehdr
             SHARED
             ${FACE_HDR_SRC}
             )


# 添加依赖库
add_library(judgehdr SHARED IMPORTED )
set_target_properties(judgehdr PROPERTIES
        IMPORTED_LOCATION "${CMAKE_SOURCE_DIR}/src/main/${ANDROID_ABI}/libjudgehdr.so")
target_link_libraries(facehdr judgehdr)


find_library(
              log-lib

              log )

target_link_libraries(
                        facehdr
                       ${log-lib} )
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
字段说明参数
${CMAKE_SOURCE_DIR}当前 CMake 规则文件的目录位置(即 CMakeLists.txt),
所以其它文件的路径可以根据这个位置来设置
include_directories使用到的头文件路径,可以包含多个路径的头文件
file可以将多个源码文件打包(这个包命名为FACE_HDR_SRC
add_library将源码编译为对应的库(将 ${FACE_HDR_SRC}的源码编译为 libfacehdr.so 库文件)SHARED .so 动态库
STATIC .a 静态库
IMPORTED 引入外部库而不是编译生成库
set_target_properties关联需要使用的其它依赖库
target_link_libraries把其它库一起打包到到目标库中
find_library关联其它库(主要是 Android Studio 提供的诸如 Log 的库)

接下来就可以运行了。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/335153
推荐阅读
相关标签
  

闽ICP备14008679号