在Android项目中引入静态库(如.a或.lib文件)主要通过以下步骤实现,需结合NDK与CMake/Android.mk配置:
1. 准备静态库文件
将预编译的静态库(如`libfoo.a`)放入项目目录,通常位于`app/src/main/cpp/libs/`下,按ABI分层(例如`armeabi-v7a`、`arm64-v8a`)。需确保库的架构与目标设备匹配。
2. 配置CMakeLists.txt
在`app`模块的`CMakeLists.txt`中声明静态库:
cmake
add_library(foo STATIC IMPORTED)
set_target_properties(foo PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libfoo.a)
target_include_directories(foo INTERFACE
${CMAKE_SOURCE_DIR}/include) # 头文件目录
target_link_libraries(native-lib foo) # 链接到目标库
3. 修改build.gradle
在模块级`build.gradle`中指定CMake路径及NDK架构过滤:
groovy
android {
defaultConfig {
externalNativeBuild {
cmake {
arguments "-DANDROID_STL=c++_shared"
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
}
externalNativeBuild {
cmake {
path "CMakeLists.txt"
}
}
}
4. 处理依赖关系
链接顺序:静态库依赖链需按顺序排列,被依赖的库放在后面。例如`target_link_libraries(native-lib dep1 dep2)`。
全局符号冲突:使用`-fvisibility=hidden`和`__attribute__((visibility("default")))`控制符号导出。
STL兼容性:确保所有静态库使用相同的STL(如`c++_shared`),避免运行时错误。
5. Android.mk方案(传统方式)
若使用`Android.mk`,需添加:
makefile
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/libfoo.a
include $(PREBUILT_STATIC_LIBRARY)
LOCAL_STATIC_LIBRARIES := foo-prebuilt
6. 调试技巧
使用`nm -gDC libfoo.a`查看库的符号表,确认函数是否正确定义。
若出现`undefined reference`错误,检查是否遗漏依赖库或ABI不匹配。
动态加载时可通过`dlopen`显式加载符号,但需确保库已打包到APK。
7. 性能与包体积优化
LTO(链接时优化):在CMake中启用`-flto`标志优化性能。
剥离符号表:发布版本使用`strip`减小库体积。
ABI过滤:仅保留目标设备架构以减少APK大小。
静态库相比动态库节省内存但增加编译体积,适合高频调用的核心算法。若需多进程共享,考虑改用动态库。
查看详情
查看详情