【发布时间】:2015-07-02 20:41:01
【问题描述】:
我正在开发一个大量使用 NDK 的 Android 应用。在 Java 方面,我们以 SDK 19 为目标,最小 SDK 为 16。有没有办法在 NDK 方面做类似的事情?
现在我们的 Application.mk 文件有APP_PLATFORM := android-16。有没有办法以平台 19 为目标,但在 NDK 端仍然兼容回 16?
【问题讨论】:
标签: android android-ndk
我正在开发一个大量使用 NDK 的 Android 应用。在 Java 方面,我们以 SDK 19 为目标,最小 SDK 为 16。有没有办法在 NDK 方面做类似的事情?
现在我们的 Application.mk 文件有APP_PLATFORM := android-16。有没有办法以平台 19 为目标,但在 NDK 端仍然兼容回 16?
【问题讨论】:
标签: android android-ndk
可行,但不太容易。
如您所知,对于 java 代码,您可以设置任何更高的目标 SDK 版本并使用此类功能,只要您确保这些代码路径仅在较新的设备上执行 - 很简单。
对于本机代码,您原则上可以将APP_PLATFORM 设置为高于您的基线,并尝试这样做,但您需要跟踪一些细节:
您不能无条件地链接到来自较新平台的函数,您需要动态加载它们。也就是说,您不需要直接调用函数并将库添加到LOCAL_LDLIBS,而是需要通过dlopen 和dlsym 加载函数,以确保二进制文件可在旧版本上加载。 (或者,您可以构建单独的共享库,其中一个共享库可以在所有平台上加载,而另一个只能在较新的平台上加载。)
一些仿生 libc 函数已更改(主要在 android-21 中,但之前也更改了一些次要函数) - 之前确实存在但已更改符号名称的函数。已更改的更常见函数之一是rand - 在android-21 之前,rand 是一个实际上称为lrand48() 的内联函数,因此您的二进制文件最终取决于lrand48,它存在于较旧的android 中版本的libc.so,而他们那里没有任何rand。在android-21 中,添加了很多这样的函数,并且删除了内联函数,因此如果您使用APP_PLATFORM := android-21 构建,您的二进制文件最终将依赖于以前不存在的函数rand。请参阅https://stackoverflow.com/a/27093163/3115956 和https://stackoverflow.com/a/27338365/3115956 了解更多详情。
请记住,您不需要将APP_PLATFORM 设置为与 java 端的目标 SDK 相同,如果您想选择性地使用较新的固件版本。
由于第二个问题,您可能根本不想设置更高的APP_PLATFORM。如果您使用dlopen(因此您实际上不需要链接.so 文件),您可以通过将这些新标头从较新的平台版本复制到您自己的项目中并使用旧的@ 构建来轻松管理987654343@.
【讨论】:
看看https://developer.android.com/ndk/guides/stable_apis.html
例如,如果您不使用 OpenGL ES 3.0 和 OpenGL ES 3.1 API 并且不链接 libGLESv3,那么您的应用与 API 级别 14 兼容。
【讨论】: