Android 单独编译 SO 文件的指南

在 Android 开发中,我们常常需要用到共享库文件,这些文件的后缀为 .so (shared object)。通常情况下,这些库文件是通过 NDK(Native Development Kit)构建的。当我们对 C/C++ 代码进行修改时,可能希望单独编译这些 .so 文件,而不需要重新编译整个项目。本文将介绍如何单独编译 .so 文件,并提供一些代码示例以供参考。

环境准备

在开始编译之前,请确保你的开发环境已正确设置,包括安装 Android NDK 和配置 ndk-build 命令。在 build.gradle 文件中添加 NDK 路径:

android {
    ...
    ndkVersion "21.3.6528147" // 根据实际版本进行调整
}

编译 SO 文件的步骤

1. 创建 JNI 目录

在你的项目根目录下创建一个 jni 文件夹,并在其中添加源代码。例如,我们创建一个简单的 C 文件 native-lib.c

#include <jni.h>

JNIEXPORT jstring JNICALL
Java_com_example_myapp_MainActivity_stringFromJNI(JNIEnv *env, jobject thiz) {
    return (*env)->NewStringUTF(env, "Hello from JNI!");
}

2. 创建 Android.mk 文件

jni 目录下创建 Android.mk 文件,定义如何编译你的 C/C++ 源代码:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    := native-lib
LOCAL_SRC_FILES := native-lib.c

include $(BUILD_SHARED_LIBRARY)

3. 创建 Application.mk 文件

如果需要指定平台和架构,可以在 jni 目录下创建 Application.mk 文件:

APP_ABI := all  # 可以指定为 armeabi-v7a、arm64-v8a 等特定架构
APP_PLATFORM := android-21  # 选择你想要支持的 API 级别

4. 编译 SO 文件

在项目根目录下,通过以下命令单独编译库文件:

cd <your_project_directory>/jni
ndk-build

编译完成后,生成的 .so 文件将放置在 libs/<architecture> 目录下。

5. 更新 Gradle配置

确保在 build.gradle 中添加如下配置,以使应用能够找到生成的 .so 文件:

android {
    ...
    sourceSets {
        main {
            jniLibs.srcDirs = ['libs']
        }
    }
}

测试 SO 文件

编译完成后,你可以在 Java/Kotlin 代码中加载并使用这些共享库。例如,在 MainActivity 中加载库并调用 JNI 方法:

static {
    System.loadLibrary("native-lib");
}

public native String stringFromJNI();

onCreate 方法中调用:

TextView tv = findViewById(R.id.sample_text);
tv.setText(stringFromJNI());

结尾

通过以上步骤,你可以成功地单独编译 Android 项目的 .so 文件,避免了每次改动都需要重新编译整个应用的烦恼。这对于大规模项目尤其有用,因为它能显著减少开发时间和提高效率。掌握这个过程后,你将能够灵活地管理你的 Android 项目,并充分利用 JNI 的强大功能。希望本指南对你有所帮助!