2022年3月25日星期五

Android项目使用预编译库

 

APP使用预编译库

默认路径

预编译库中的so放到src/main/jniLibs/<ABI>下,AndroidStudio打包时会自动将预编译的so文件打包进生成的产物APK/AAR

.
├── build.gradle
└── src
    ├── main
    │   ├── AndroidManifest.xml
    │   ├── java
    │   └── jniLibs
    │       ├── arm64-v8a
    │       │   └── libprebuilt.so
    │       └── armeabi-v7a
    │           └── libprebuilt.so
    

自定义路径

预编译库中的so放置到任意路径:

.
├── build.gradle
├── libs
│   ├── arm64-v8a
│   │   └── libprebuilt.so
│   └── armeabi-v7a
│       └── libprebuilt.so
└── src
    ├── main
    │   ├── AndroidManifest.xml
    │   └── java
    

配置如下:

android {
    sourceSets {
main {
jniLibs.srcDirs 'libs'
}
}
}

NDK引用预编译库

NDK项目中也可以引用预编译库。

这里注意不要将预编译库放到src/main/jniLibs/<ABI>下,或者使用android.sourceSets.main.jniLibs.srcDirs来配置预编译库路径;而是在Android.mdCMakeLists.txt中配置

ndk-build

TODO

cmake

下面是一个简单项目:

.
├── mylib
│   ├── build.gradle
│   └── src
│       └── main
│           └── cpp
│               ├── CMakeLists.txt
│               ├── include
│               │   └── my_lib.h
│               └── my_lib.cpp
└── prebuilt
    ├── include
    │   └── prebuilt.h
    └── lib
        ├── arm64-v8a
        │   └── libprebuilt.so
        └── armeabi-v7a
            └── libprebuilt.so

配置如下:

cmake_minimum_required(VERSION 3.10.2)

# prebuilt lib root dir
set(PREBUILT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../../prebuilt)
set(PREBUILT_LIB_DIR ${PREBUILT_DIR}/lib/${ANDROID_ABI})

# libprebuilt.so
add_library(prebuilt STATIC IMPORTED)
set_target_properties(prebuilt PROPERTIES IMPORTED_LOCATION
        ${PREBUILT_LIB_DIR}/libprebuilt.so)

# my_lib project
project("my_lib")

# add source files to my_lib project
add_library(
        my_lib
        SHARED
        my_lib.cpp)

# hide symobols
set_target_properties(my_lib PROPERTIES CXX_VISIBILITY_PRESET hidden)

# find android log library
find_library(
        log-lib
        log)

# include dirs
target_include_directories(
        my_lib
        PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/include # include dir of my_lib
        ${PREBUILT_DIR}/include # include dir of prebuilt library
)

# link prebuilt library & android log library to my_lib
target_link_libraries(
        my_lib

        prebuilt

        ${log-lib})

如上,在my_lib项目中引入了libprebuilt.so库,在打包时libprebuilt.so会自动打包到生成的APK/AAR

NDK禁止打包预编译库

譬如我们创建的Android library项目引用了三方库libprebuilt.so,但是我们希望在生成的产物中不包含libprebuilt.so文件,单独提供该文件或由接入方自己导入这个库文件,可以在打包时排除这个文件:

plugins {
id 'com.android.library'
}

android {
defaultConfig {
externalNativeBuild {
cmake {
cppFlags ''
}
}
}

externalNativeBuild {
cmake {
path file('src/main/cpp/CMakeLists.txt')
version '3.18.1'
}
}
packagingOptions {
jniLibs.excludes += '**/libprebuilt.so' // 打包时排除libprebuilt.so文件
}
}

参考

JniLibsPackagingOptions

Android logcat

Log等级 Android log 等级在 android/log.h 中定义如下: typedef   enum   android_LogPriority {    /** For internal use only. */ ANDROID_LOG_UNKNOWN =...