如何为 Android 不同平台打包原生预构建库
How to package native prebuilts libraries for Android different platforms
为了编译本机预构建库,我们使用带有这两个选项 -DANDROID_ABI
和 -DANDROID_PLATFORM
的 NDK 工具链,因此如果我们支持 android-28
、android-29
平台和 armeabi-v7a
、arm64-v8a
、x86
、x86_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.3
和 Gradle 5.6.4
。
您可以选择平台作为构建的一部分,因为这决定了您的代码将与哪些设备兼容。如果您的目标是 21,则不能保证您的代码 运行 适用于 Lollipop 之前的任何版本。
虽然应用程序是向前兼容的,所以如果你为 21 构建你将 运行 在 Lollipop 和之后的所有内容(除了非常罕见的例外,只要你坚持 [=14= 定义的行为就非常罕见) ] API)。这就是为什么你不需要为每个平台打包库,只需要你支持的最旧的。
为了编译本机预构建库,我们使用带有这两个选项 -DANDROID_ABI
和 -DANDROID_PLATFORM
的 NDK 工具链,因此如果我们支持 android-28
、android-29
平台和 armeabi-v7a
、arm64-v8a
、x86
、x86_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.3
和 Gradle 5.6.4
。
您可以选择平台作为构建的一部分,因为这决定了您的代码将与哪些设备兼容。如果您的目标是 21,则不能保证您的代码 运行 适用于 Lollipop 之前的任何版本。
虽然应用程序是向前兼容的,所以如果你为 21 构建你将 运行 在 Lollipop 和之后的所有内容(除了非常罕见的例外,只要你坚持 [=14= 定义的行为就非常罕见) ] API)。这就是为什么你不需要为每个平台打包库,只需要你支持的最旧的。