在生成的.aar中捆绑静态/共享库

时间:2017-11-07 16:40:14

标签: android cmake java-native-interface

我正在使用Android Studio生成.aar个Android模块。它允许我公开Java类和方法,以便在其他项目中调用它们。

其中一种方法是在静态库中定义的C ++方法,并通过JNI从Java调用。

导入.aar并尝试调用此类方法时,我接受了"未定义的引用"。解压缩.aar并搜索它会告诉我它不包含通过Android Studio和Cmake生成的静态/共享库的任何痕迹。

我该如何解决这个问题?

生成库的CMakeLists.txt的内容:

cmake_minimum_required(VERSION 3.4.1)
set(GCC_COVERAGE_LINK_FLAGS "--whole-archive")

# Find the android-log library for debug purposes
find_library(log-lib log)

# Set directory variables
set(LIBS_DIR ${CMAKE_SOURCE_DIR}/libs)
set(SRC_DIR ${CMAKE_SOURCE_DIR})

# Compiles the static transaction library from sources
add_library(code-logic
            STATIC
            ${SRC_DIR}/src/CustomAPI.cpp
            ${SRC_DIR}/src/ParameterAPI.cpp )
include_directories(${SRC_DIR}/inc/)

# Compiled native-lib from native cpp source code
add_library(native-lib SHARED src/main/cpp/native-lib.cpp)
# Link it with android-log and transaction-logic
target_link_libraries(native-lib
                      code-logic
                      log       )

我可以看到这些库确实是在ProjectDirectory/app/.externalNativeBuild/cmake/release/${ARCH}/libs/${ARCH}/lib.so中生成的,但它们不会出现在intermediates/文件夹中或生成的.aar中的任何位置。

2 个答案:

答案 0 :(得分:0)

您可能必须在build.gradle中设置libs目录

   android {
   ...
     main {
      jniLibs.srcDirs = [ 'jni/libs', 'externalNativeBuild/cmake/release/${ARCH}/libs/${ARCH}' ] // Where generated .so files are placed.
       ...
     }
  }

答案 1 :(得分:0)

我无法找到任何"内置"解决方案,所以我在构建过程中添加了一个脚本,在最后调用。它"解压缩" .aar文件,通过添加Android Studio编译的静态/共享库来编辑它,然后"重新压缩"它成为.aar文件。这是脚本:

#! /usr/bin/env /bin/bash

OUT_DIR=`pwd`
LIB_DIR="${OUT_DIR}/tmp/libs"
JNI_DIR="${OUT_DIR}/tmp/jni"
BASE_DIR="${OUT_DIR}/.."
PROJ_NAME="PROJECT_NAME_BASE_DIRECTORY"
LIB_NAME="LIB_NAME.aar"
BUILD_DIR="${BASE_DIR}/${PROJ_NAME}/app/.externalNativeBuild/cmake/release"

rm -rf ./tmp/ && mkdir ./tmp/
unzip ${LIB_NAME} -d ./tmp/

(
  cd "${BUILD_DIR}" \
  && for f in `find . -name "*\.a"`
  do
      mkdir -p "${JNI_DIR}/"$(basename $(dirname "${f}"));
      cp "${f}" "${JNI_DIR}"/$(basename $(dirname "${f}"));
  done \
  && for f in `find . -name "*\.so"`
  do
      mkdir -p "${JNI_DIR}/"$(basename $(dirname "${f}"));
      cp "${f}" "${JNI_DIR}"/$(basename $(dirname "${f}"));
  done
)

rm -f ${LIB_NAME}.aar
jar cvf ${LIB_NAME}.aar -C ./tmp/ .
rm -rf ./tmp/