What Is the Relation Between App_Platform, Android:Minsdkversion and Android:Targetsdkversion

What is the relation between APP_PLATFORM, android:minSdkVersion and android:targetSdkVersion?


  1. android:minSdkVersion is the minimum OS version that your app expects.

  2. android:targetSdkVersion is essentially the maximum OS version that you've designed your app to work with. Here's an example of how this works. Imagine that you tested your app fine with API 19 and you release your app with android:targetSdkVersion=19. Then Google decides to release API 20 with a change in behavior of some API, but they don't want to change the behavior for old apps (to prevent from breaking them). So when your app starts up, Android sees that your app has targetSdkVersion=19, so it gives you the old API behavior, but if some other app says targetSdkVersion=20, Android will give it the new API behavior.

  3. APP_PLATFORM is the version of the native headers and libraries that the NDK will compile your native code with. If you set APP_PLATFORM to a specific value and you use APIs that are only available in that platform version, then your app will not run properly on older platforms. So APP_PLATFORM is a minimum value. The solution is to use a lower value and not use those newer APIs, or to write code that decides at runtime whether to call the new APIs or not (and probably use dlopen/dlsym).

It seems like in general it doesn't make sense to use an APP_PLATFORM value newer than android:minSdkVersion, unless you're doing some special (like being careful not to call new APIs by checking the version at runtime, plus making sure not to link to new APIs and instead using dlopen/dlsym).

So if you use APP_PLATFORM=13 and you call AMotionEvent_getAxisValue (which is not in earlier platform headers, implying that it isn't available at runtime on earlier platforms), your app will not run on devices with API < 13. The one caveat would be if AMotionEvent_getAxisValue is actually available on older versions, but it just wasn't in the header/library files or it just wasn't documented. But I don't know if that's the case for this particular API (basically, that would require more research and risk analysis of whether you want to depend on something unsupported).

Relation between android:minSdkVersion, android:targetSdkVersion and target

To describe one at a time:

  • android:minSdkVersion helps Google Play filter apps for the user based on their device. For instance, with minSdkVersion="7", someone browsing with a device that only supports 6 won't see your app on Google Play, and thus won't download it, find it doesn't work, and leave a bad review :)

  • android:targetSdkVersion is a signal to the device about which version of the API your app was tested against. New behaviors are often available by default with new versions of the platform, for applications that target at least that version of the platform. For instance, by setting your targetSdkVersion to 11 or higher, you get an overflow menu in the ActionBar (for Honeycomb and up devices) instead of the "legacy menu button of shame".

  • project.properties target is a signal to your local build system regarding which version of the platform you should be compiling your code against. Generally it's best to just set this to whatever you have set for the targetSdkVersion.

What am I missing? If I'm building against 15, how is it running on
android-7?

Android maintains backwards compatibility for just this reason. When you use API's that were added in version 15 of the platform, obviously they won't be there on a device running an an older device.

However, it's possible (and encouraged) to design your application in such a way as to take advantage of features added on new platforms, but "degrade gracefully" such that your application continues to run on older ones. There's an Android Training lesson on just this topic, called Supporting Different Platform Versions.

Android NDK: WARNING: APP_PLATFORM android-9 is larger than android:minSdkVersion 8

It seems that you are using Android-9 as runtime. You can put APP_PLATFORM := android-8 in your Application.mk file and the warning will disappear.

How Get rid of NDK compiler warning: APP_PLATFORM is larger.. and Invalid package

Regarding "package", this is most likely some crlf problem with your XML file. Check the line end characters there. Or, maybe something is wrong in your project.properties file.

The APP_PLATFORM warning is actually correct: your APP_PLATFORM (android-14) is larger than android:minSdkVersion you set in AndroidManifest.xml. This is only a warning to remind you about this (legitimate) situation, so that at certain stage you decide to drop support for very dated devices.

How do I set the APP-PLATFORM in Application.mk to match the targetSDKVersion in Android Studio 3.2.1

You don't. You NDK API version needs to match your minSdkVersion. You app is not guaranteed to run on any release lower than your NDK API version. externalNativeBuild handles this automatically. If you need to use API 28 for your NDK libraries, you need to set your minSdkVersion to 28.

However, I don't think that's the problem here. This question has come up three times in the last two weeks. It looks like AndroidLibSVM was built against android-24 or higher. As such, it cannot be used on devices older than that API level (all the other questions were trying to use it on android-23).

For Android does CMAKE_SYSTEM_VERSION mean the minimum api level or the target api level?

It's the version of the operating system for which CMake is to build. CMake sets it to the Android API level of the target platform. Usually, we set CMAKE_ANDROID_API instead of manipulating CMAKE_SYSTEM_VERSION directly.

Unfortunately, the NDK toolchain file, which is used by the Android gradle plugin we all use with Android Studio, uses an entirely different set of variables, and sets this to 1 to "Inhibit all of CMake's own NDK handling code". It expects ANDROID_PLATFORM instead.

At any rate, your question about minimum vs. target API level is very important. Unlike Android SDK, the NDK platform support is not backwards compatible. With Java, the best practice is to set the target API as high as possible (and also compile using the latest available SDK), and carefully use the APIs that may be unavailable on older devices.

With C++, we must work differently. Even the latest NDK r18 has 'platforms' going back to android-16, so that you could build your C++ code to run on this older system, too. In terms of Android SDK, this corresponds to minSdkVersion.

Android NDK and Newer API Support

It's doable, but it is not too easy.

For the java code, as you know, you can set any higher target SDK version and use such features, as long as you make sure that those codepaths only are executed on the newer devices - simple.

For the native code, you can in principle set a higher APP_PLATFORM than your baseline, and try to do the same, but there's a few details you need to keep track of:

  • You can't unconditionally link to functions from the newer platform, you need to load them dynamically. That is, instead of calling functions directly and adding the libraries to LOCAL_LDLIBS, you need to load the functions via dlopen and dlsym instead, to make sure that the binary is loadable on the older versions. (Or alternatively, you can build separate shared libraries, where one shared library can be loaded on all platform, while another one only can be loaded on newer platforms.)

  • Some bionic libc functions have changed (mainly in android-21, but some minor ones also changed before that) - functions that did exist before but have changed symbol name. One of the more common functions that has changed is rand - prior to android-21, rand was an inline function that actually called lrand48(), so your binary ended up depending on lrand48 which existed in the older android versions' libc.so, while they didn't have any rand there. In android-21, a lot of such functions have been added, and the inline functions removed, so if you build with APP_PLATFORM := android-21, your binary will end up depending on the function rand which didn't exist before. See https://stackoverflow.com/a/27093163/3115956 and https://stackoverflow.com/a/27338365/3115956 for more details about this.

  • Keep in mind that you don't need to set APP_PLATFORM to the same as the target SDK on the java side, you only (may) need to set it if you want to selectively use newer features on newer firmware versions.

Due to the second issue you might not want to set a higher APP_PLATFORM at all. If you use dlopen (so you don't actually need the .so files to link against), you can manage pretty easily by copying those new headers from the newer platform version into your own project, and building with the older APP_PLATFORM.



Related Topics



Leave a reply



Submit