Lots of good explanations in earlier answers, but none link to the official docs. If curious, see
https://developer.android.com/guide/topics/manifest/uses-sdk-element for:
The Android system will prevent the user from installing the application if the system's API Level is lower than the value specified in this attribute.
Aside: if you use the NDK to run native code, minSdkVersion
also impacts the NDK's API availability. (https://developer.android.com/ndk/guides/sdk-versions)
This attribute informs the system that you have tested against the
target version and the system should not enable any compatibility
behaviors to maintain your app's forward-compatibility with the target
version. The application is still able to run on older versions (down
to minSdkVersion).
As Android evolves with each new version, some behaviors and even
appearances might change. However, if the API level of the platform is
higher than the version declared by your app's targetSdkVersion, the
system may enable compatibility behaviors to ensure that your app
continues to work the way you expect. You can disable such
compatibility behaviors by specifying targetSdkVersion to match the
API level of the platform on which it's running. For example, setting
this value to "11" or higher allows the system to apply a new default
theme (Holo) to your app when running on Android 3.0 or higher and
also disables screen compatibility mode when running on larger screens
(because support for API level 11 implicitly supports larger screens).
So the assumption is that you developed the app with the target API in mind, and have tested that everything looks/behaves as you expected, esp if you're trying to use features introduced in this API. Furthermore, your code should be able to handle platforms that don't have that new feature (down to your minSdkVersion
, e.g. checking your code handles missing APIs that you use gracefully, etc). But even newer Android versions may do things to keep your app running, which might otherwise break or look even funkier if the OS didn't enable "compatibility behaviors".
See https://developer.android.com/studio/build for:
compileSdkVersion specifies the Android API level Gradle should use to
compile your app. This means your app can use the API features included in
this API level and lower.
Ideally you'd set target & compile versions the same to the highest release, and of course you don't have to use any of the new features. But you may wish to keep your target at an older version you've already released, while using a newer compile version for better warnings/errors, until you're ready to update the target version. In the past it also let one use newer Java language features in their code with an Android Gradle plugin upgrade, independent of the target Android APIs.
Lastly, don't forget about Google's more recent target API level requirements, which basically require you to release a build targeting up-to-date API levels by a certain date if you want to still be available to users on the Play store that use an OS newer than your target API. This is to motivate the app dev community make available newer performance/security enhancements (like giving the user more privacy options when you request location info).
Every version of Android released since 9 lists behavior changes that will impact all apps regardless of your targetSdkVersion
(e.g. here's Android 12's), and what changes when you specifically target it (e.g. Behavior changes: Apps targeting Android 12. When the next version is in preview is a good time to start checking your app's compatibility with the upcoming release, even if it's just that any compat modes are ok without changing your compileSdkVersion
, if you aren't prepping to target it yet. The Compatibility framework tools can help with that and in the migration to using new APIs.