There are 4 places in
build.gradle where Android SDK version can be defined. This article describes their meanings and purposes. All of them are connected with the concept of API level. In general, it corresponds to Android system version and the newer device and system the higher API level is. Certain parts of Android framework APIs are available since particular API level and won’t work on systems with older API levels. See What is API Level? for more information about API level itself. See also Dashboards to see what is the market share of devices with particular API levels (not listed versions have value less than 0.1%).
minSdkVersion is the most obvious one. It simply tells that app requires at least given API level. It cannot be installed in any normal way on a system with lower API level, this includes commandline via
adb, manual installation via system UI (installation from unknown source), installation from IDE or gradle scripts and Google Play Store. In the last case app won’t be even shown in search results in Play Store app. In opened app page in store, installation option will be unavailable. Default value is
1 which means that in most of the currently developed apps it needs to be set explicitly.
maxSdkVersion which usage not recommended is a partial opposite of
minSdkVersion. Difference is that since Android 2.0.1 (API level 6) it is not used in runtime checks but only by Google Play Store to filter results. Using this attribute is almost always not needed since Android API is (almost always) backwards compatible. Reasonable use cases concern using removed APIs (eg. android.hardware.location or undocumented features like App Ops. If this attribute is not defined there is no maximum API level restriction.
targetSdkVersion is a hint for system on which app is running, indicating which API level is app designed for. In other words indicates rules of which API level have been used when developing app. It is meaningful only when API level at runtime is higher than
minSdkVersion. Recommended way is to set it to the highest API on which app has been tested.
compileSdkVersion is the API level which app is compiled against. Its value determines which APIs can be used in app code (using APIs introduced in higher API levels will cause a compilation error). App can run on device with lower API level if code execution paths do not attempt to invoke any unavailable APIs (except constans which will be simply copied into an app). Value should be always set to the highest stable API level, even if app does not use any API from it. This is due to the fact that some API may be deprecated, stop working – invoked method may start doing nothing like WebView.htmlonChildViewAdded(android.view.View, android.view.View), callbacks may stop being called like WebChromeClient#onJsTimeout(). In such cases compiler warning is raised. Only API levels of installed SDK platforms can be used as a values.
All attributes are defined per build variant except
compileSdkVersion, which is defined per the whole module. There is also a restriction that
minSdkVersion of given module cannot be lower than the value in any dependent module eg. you cannot use version 7.5.0 of Google Play Services library (which
9) in an app which has that value set to
targetSdkVersion should not be set to value higher than
compileSdkVersion, because it means that app is targeting something which can not be known yet.