在 Android NDK 中使用比 Android 清单中最低 API 更高的 API 是否有效?

Is it valid to use a higher API in the Android NDK than the minimum in Android Manifest?

本文关键字:Android API 是否 有效 单中最 NDK      更新时间:2023-10-16

我有一个Android应用程序,它指定最低API级别为15,目标API为17。通常,我指定android-15(<ndk>/platforms/android-15)作为我的API级别(通过--sysroot)作为我的应用程序的原生部分使用Android NDK,因为AFAIK的最低目标应该是通过NDK。

但是,NDK r14 中的 Clang + LLVM STL 似乎存在一个错误,除非您在 NDK 端使用最少android-21,否则无法正确定义strtold等符号。

所以我的问题是:使用为android-21编译的*.so,其APK目标最小SDK为15,目标SDK为17,会产生什么影响?我能侥幸逃脱吗?

简短回答:否。请参阅我们的常见问题文档。

NDK 中的目标 API 级别

与 Java 中的目标 API 级别具有非常不同的含义targetSdkVersion。NDK 目标 API 级别是您应用支持的最低API 级别。在ndk-build中,这是您的APP_PLATFORM设置。

由于对函数的引用(通常)是在加载库时而不是在首次调用库时解析的,因此不能引用并不总是存在的 API,也不能通过 API 级别检查来保护它们的使用。如果提到它们,它们必须存在。

更长,更迂腐的答案:仅在它不是真的高的特殊情况下。例如,NDK 中没有 android-20。在这种情况下,您将回退到 android-19,因此可以将 NDK 目标 API 设置为 android-20,minSdkVersion为 19,因为您实际上最终都会使用 android-19。

如果我没记错的话,在 ndk 中指定一个最小值将包括针对该版本的 android 附带的库的标头和链接。 从理论上讲,只要 1.)库存在于旧版本和 2.)这些库与旧版本兼容。这意味着在二进制文件中类定义或符号的存在、缺失或位置方面没有重大变化,通常 linux 非常擅长保持 ABI 兼容性,但它不是防弹的,对于 android,谷歌似乎在他们喜欢的时候添加和删除东西几乎没有任何理由。当他们破坏或保留旧版本中的 ABI 兼容性时,他们当然不会做广告。

我认为现代版本的 android 也会在加载库代码中警告您,如果您尝试加载链接到较新平台的库。这看起来不太好。(我一定是想象到的)

所有这些都意味着你可能不应该这样做。在您的情况下,我可能会建议不要使用 LLVM STL(或静态链接它),因为这是未定义符号的来源,LLVM STL 在平台 21 之前没有在设备上发布,因此您无法链接到它并针对这些设备。