如何为 Android 不同平台打包原生预构建库

How to package native prebuilts libraries for Android different platforms

为了编译本机预构建库,我们使用带有这两个选项 -DANDROID_ABI-DANDROID_PLATFORM 的 NDK 工具链,因此如果我们支持 android-28android-29 平台和 armeabi-v7aarm64-v8ax86x86_6 ABIs 我们将必须生成的库集:

.
├── android-28
│   ├── arm64-v8a
│   │   └── libMy.so
│   ├── armeabi-v7a
│   │   └── libMy.so
│   ├── x86
│   │   └── libMy.so
│   └── x86_64
│       └── libMy.so
└── android-29
    ├── arm64-v8a
    │   └── libMy.so
    ├── armeabi-v7a
    │   └── libMy.so
    ├── x86
    │   └── libMy.so
    └── x86_64
        └── libMy.so

我们可以很容易地在 Android cmake 中使用这样获得的预构建,因为它支持 ${ANDROID_PLATFORM}${ANDROID_ABI} 变量,例如CMakeLists.txt:

...
list(APPEND CMAKE_FIND_ROOT_PATH ${THIRDPARTY_PREBUILT_DIR}/${ANDROID_PLATFORM}/${ANDROID_ABI}/mylib)
...

但是将这些预构建打包到 APK 中对我来说似乎不太清楚,因为 app/src/main/jniLibs 不支持平台层次结构,但仅支持 ABI:

.
└── jniLibs
    ├── arm64-v8a
    │   └── libMy.so
    ├── armeabi-v7a
    │   └── libMy.so
    ├── x86
    │   └── libMy.so
    └── x86_64
        └── libMy.so

并且在输出中也是相同的结构 app-debug.apk/lib

所以 问题:为什么我们在工具链和 Android cmake 选项中有针对不同平台的选项,但本地库(jni 库)的打包会忽略它们?

我使用 Android Studio 3.6.3Gradle 5.6.4

您可以选择平台作为构建的一部分,因为这决定了您的代码将与哪些设备兼容。如果您的目标是 21,则不能保证您的代码 运行 适用于 Lollipop 之前的任何版本。

虽然应用程序是向前兼容的,所以如果你为 21 构建你将 运行 在 Lollipop 和之后的所有内容(除了非常罕见的例外,只要你坚持 [=14= 定义的行为就非常罕见) ] API)。这就是为什么你不需要为每个平台打包库,只需要你支持的最旧的。