【发布时间】:2021-05-09 16:18:45
【问题描述】:
为了编译原生预建库,我们使用 NDK 工具链和这两个选项 -DANDROID_ABI 和 -DANDROID_PLATFORM,所以如果我们支持 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。
【问题讨论】:
-
您是否需要为这两个平台级别提供单独的库,或者您可以将它们组合成一个库?如果它们确实需要单独的库,那么您可能需要为不同的最低 API 级别构建单独的应用程序包/APK(参见例如developer.android.com/studio/build/…)。
-
@Michel:感谢您的评论。我需要构建一些第三方库,然后像 Android 应用程序项目中的预建库一样使用它们,但是为了编译它们,NDK 工具链需要我指定
-DANDROID_PLATFORM参数,但这些库不依赖于特定的 Android API(28 或 29 或其他)只有应用程序需要支持 28 和 29。所以我会像 @Dan Albert 回答的那样做 - 将应用最旧的版本来编译第三方库。
标签: android android-studio gradle cmake android-ndk