Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
187 views
in Technique[技术] by (71.8m points)

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

I'm developing an Android app that uses NDK features. My app defines android:minSdkVersion and android:targetSdkVersion in AndroidManifest.xml and APP_PLATFORM in jni/Application.mk.

My current understanding is that android:minSdkVersion decalres minimal supported OS version, android:targetSdkVersion declares Java library version to be linked against, and APP_PLATFORM declares C++ library to be linked against.

Two questions:

  1. Is my understanding correct?

  2. Is it Ok for APP_PLATFORM to be greater that android:minSdkVersion? Or they must be equal each other?

The reason for my question: I want my app to be available for devices with API >= 10, but I need to use NDK functions (like AMotionEvent_getAxisValue) that are defined in platformsandroid-13 folder in NDK. So I use android:minSdkVersion=10 and APP_PLATFORM=13. Project compiles successfully, but would it be runnable on API 10-12 devices?

Question&Answers:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This answer brings together hard-to-find but important information from many excellent websites and stackoverflow answers/comments on this under-documented NDK subject:

Avoiding Crashes: NDK Version, minSdKVersion, targetSdkVersion, and APP_PLATFORM (in project.properties)

The short version

To prevent your native Android app from mysteriously crashing on older customer devices, the short answer is to make your NDK APP_PLATFORM (in project.properties or Application.mk) the same as your minSdkVersion (in AndroidManifest.xml).

But depending on what NDK features you use, doing so may severely limit the set of customers who can download your app.

To find out why that is and whether you have other options, read on...

Four different concepts

  • NDK Version (e.g. r10e, r13b): this is the version of the Android NDK release (the tar/zip file) you download from Google. Here are all the NDK versions

  • minSdkVersion (e.g. 15,19,21) is a setting you make in your AndroidManifest.xml in a <uses-sdk> element under the <manifest> element. This setting affects both NDK (native) and Java development.

  • targetSdkVersion (e.g. 15,19,21) is a different setting you make in your AndroidManifest.xml in a <uses-sdk> element under the <manifest> element. This setting affects only Java development.

  • APP_PLATFORM (e.g. 15,19,21) is a setting you make in your Native NDK project. Typically this setting is found in the project.properties file at the root of your project as the last number at the end of the target= line, e.g. target=Google Inc.:Google APIs:21 for level 21 (and usually the way that "21" got there is by being the -t/--target option to a command-line invocation of the android create project or android update project command). You can also make this setting by putting APP_PLATFORM := android-21 into your Application.mk file.

Three of these concepts use API Level Numbers

minSdkVersion, targetSdkVersion and APP_PLATFORM use Android's consistent numbering scheme for API levels:

Click here to see Google's API Level Chart

As you can see, the levels roughly correspond to Android releases, but do not even remotely match the number of the Android release (that would be too easy). For example, API level 10 corresponds to Android OS 2.3.3 and 2.3.4.

The cute code-names like "Lollipop" and "Nougat" are at a coarser granularity than API versions. For example, several API versions (21 and 22) are "Lollipop"

These same API version numbers are encoded by the Java Build.VERSION_CODES type:

Click here to see Build.VERSION_CODES

For example, level 22 is LOLLIPOP_MR1

Not every number exists for each concept. For example, you might want to support API level 10, but there is no APP_PLATFORM 10 so you would go back to the last available APP_PLATFORM, APP_PLATFORM 9.

Click here to see distribution of API versions in the installed base in the wild

What is minSdkVersion?

This setting is by far the easiest to understand. When you set minSdkVersion to, say, 21 (corresponding to Android OS 5.0), that means that the Google Play Store will only advertise your app as supporting Android OS 5.0 and beyond, and Android will prevent users from installing your app if their Android device has lower than Android OS 5.0 installed.

So minSdkVersion is the lowest OS you support. Nice and simple.

This setting obviously has implications both for Java and C code: you want to set it to the lowest OS version that both parts of your code can support.

Both targetSdkVersion and APP_PLATFORM must be greater than or equal to minSdkVersion.

What is targetSdkVersion?

This setting only has effect in the Android Java world (it has no effect on your C NDK code). Its fulfills a purpose in the Android Java world that is similar to APP_PLATFORM in the Android C NDK world.

Sometimes you want your app to support older devices, but also use new features only available on newer Java API versions.

For example, Android added a nifty Java VoiceInteractor API that's only supported in API 23 (Android 6.0) or later. You might want to support VoiceInteractor if your customers have a new device, but still have your app run on older devices.

By setting targetSdkVersion to 23, you are making a simple contract with Android:

  • Android agrees to give your app code access to API-23-only Java features like VoiceInteractor
  • In return, you agree to check, at runtime in your Java code, whether that feature is available on the customer's device before calling it (otherwise your app will crash).

This contract works because in Java, it is "ok" if your code has references to classes/methods that might not exist on the customer's device, as long as you don't call them.

The contract applies to all Android Java features added after your minSdkVersion up to and including your targetSdkVersion.

In addition to giving you access to certain new Java APIs, the targetSdkVersion setting also enables or disables certain well-documented compatibility behaviors:

Click here to see which behavior changes come with each targetSdkVersion

These well-documented changes also form a kind of contract. For example, around Android 4, Google migrated their Android device designs away from having a dedicated menu button and towards having an on-screen Action bar. If your app has a targetSdkVersion lower than 14 (Android 4.0.1), Google would put a software menu button up on the screen to make sure your app kept working even if the device didn't have a dedicated menu button. But by choosing a targetSdkVersion greater than or equal to 14 at build time, you are promising Google that you either don't have a menu or you use an Action bar, so Google no longer puts up the software menu button.

What is APP_PLATFORM?

APP_PLATFORM performs a similar function in the C NDK world that targetSdkVersion performs in the Java world.

But, sadly, due to a combination of limitations in the C language and bad behavior by Google, APP_PLATFORM is significantly more dangerous and, frankly, nearly unusable.

Let's start from the beginning...

APP_PLATFORM is an NDK-only setting that tells the build-ndk tool which subdirectory of your NDK to look in for certain key include files and libraries which collectively are referred to as an NDK "platform." Each NDK distribution (each NDK tar/zip that we developers download from Google) contains multiple platforms.

For example, if you set APP_PLATFORM to android-21, build-ndk will look in:

$(ndk_directory)/platforms/android-21/arch-$(architecture)/usr/include
$(ndk_directory)/platforms/android-21/arch-$(architecture)/usr/lib

for include files and libraries.

If you installed your NDK by simply downloading a zip/tar from Google's NDK Downloads Website, then $(ndk_directory) is simply the directory where you extracted the file.

If you installed your NDK by first downloading the Android (Java) SDK and then running the Android SDK Manager to install the "NDK" item, then $(ndk_directory) is $(sdk_directory)/ndk-bundle, where $(sdk_directory) is wherever your SDK is installed.

$(architecture) is arm, arm64, x86, etc.

What is in a "platform"?

The $(ndk_directory)/platforms/android-XX directory contains two super-important things:

  • all your C library calls like fopen(), atof(), sprintf() etc. The C library on Android is called "bionic."
  • Android-specific NDK calls/types/defines like AInputQueue and EGLContext

What changes at different APP_PLATFORM levels?

In each android-XX version, Google adds more calls to the NDK. For example,

  • APP_PLATFORM API level 9 added the very useful NativeActivity
  • APP_PLATFORM API level 18 added OpenGL ES 3.0

Some APP_PLATFORM versions also add calls to the C library, and/or "fix" things that are missing (for example, the token PTHREAD_KEYS_MAX got added in APP_PLATFORM 21).

Click here to read Google's incomplete documentation on what changed in each APP_PLATFORM level

So far this is similar to the Java world. Nobody expects Google or any other OS vendor to make every new feature available on old devices, especially when those features rely on hardware only found on newer devices (e.g. faster processors, new camera features, new audio features).

But Google's NDK team did a naughty thing that the Java team did not.

In some APP_PLATFORM versions, Google made gratuitous, breaking API changes that cannot possibly be excused by any legitimate argument such as those above.

These are the types of breaking API changes that Android Java developers would never accept. For example, Google has

  • renamed C library functions and
  • changed C library functions from being inlined to being not inlined

The most serious case of this was APP_PLATFORM 21, where Google made many breaking changes that generated an extremely high number of stackoverflow issues (many examples <a href="https://stackoverflow.com/questions/31194260/android-nd


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...