Karol WrótniakAndroid Developer

Introduction

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

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

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

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 targetSdkVersion, in such case some additional compatibility behaviors can be turned on. One of the most noticeable example is introducing JavascriptInterface annotation in API level 17. Starting from it annotation is mandatory and non annotated methods will not work. Developers working before API level 17 was released could not know about that, so apps targeting API level lower than 17 will work without that annotation even on systems with higher API levels. If value is not defined then it will default to minSdkVersion. Recommended way is to set it to the highest API on which app has been tested.

compileSdkVersion

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.

Additional information

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 minSdkVersion is 9) in an app which has that value set to 8. Moreover, targetSdkVersion should not be set to value higher than compileSdkVersion, because it means that app is targeting something which can not be known yet.