我正在开发一款大量使用NDK的Android应用。在Java方面,我们使用16的最小SDK来定位SDK 19.有没有办法在NDK方面做类似的事情?
现在我们的Application.mk文件有APP_PLATFORM := android-16
。有没有办法定位平台19,但在NDK方面仍然具有兼容性16?
答案 0 :(得分:4)
这是可行的,但这并不容易。
对于java代码,如您所知,您可以设置任何更高目标SDK版本并使用此类功能,只要您确保这些代码路径仅在较新的设备上执行 - 简单。
对于本机代码,您原则上可以设置比基线更高的APP_PLATFORM
,并尝试执行相同的操作,但是您需要跟踪一些详细信息:
您无法无条件地链接到较新平台的功能,您需要动态加载它们。也就是说,不是直接调用函数并将库添加到LOCAL_LDLIBS
,而是需要通过dlopen
和dlsym
加载函数,以确保二进制文件可以在较旧版本上加载版本。 (或者,您可以构建单独的共享库,其中一个共享库可以在所有平台上加载,而另一个只能在较新的平台上加载。)
一些仿生libc函数已经改变(主要在android-21
,但在此之前也发生了一些次要改变) - 以前存在但已经改变了符号名称的函数。已更改的常见功能之一是rand
- 在android-21
之前,rand
是实际调用lrand48()
的内联函数,因此您的二进制文件最终取决于{{ {1}}存在于较旧的Android版本中。 lrand48
,虽然他们没有libc.so
。在rand
中,添加了很多此类函数,并删除了内联函数,因此如果使用android-21
进行构建,则二进制文件最终将取决于函数APP_PLATFORM := android-21
而不是&# 39; t之前存在。有关详情,请参阅https://stackoverflow.com/a/27093163/3115956和https://stackoverflow.com/a/27338365/3115956。
请注意,您不需要将rand
设置为与java端的目标SDK相同,只有(如果您想)选择性地设置它在较新的固件版本上使用较新的功能。
由于第二个问题,您可能根本不想设置更高的APP_PLATFORM
。如果您使用APP_PLATFORM
(因此您实际上并不需要链接dlopen
个文件),您可以通过将新平台版本中的新标头复制到您自己的项目中来轻松管理,并使用较早的.so
进行构建。
答案 1 :(得分:1)
查看https://developer.android.com/ndk/guides/stable_apis.html
例如,如果您不使用OpenGL ES 3.0和OpenGL ES 3.1 API而不链接libGLESv3,那么您的应用程序与API级别14兼容。