Android API level, backward and forward compatibility

Good evening friends. We have prepared a useful translation for future students of the Android Developer. Advanced Course . We are happy to share this material with you.








If you are reading this article, it means that you may be interested in such things as:









All these concepts are related to each other, and I will try to explain them to you in this article in a simple but effective way.



To do this, you need to understand the difference between the SDK and the API and know what the API level is in the Android ecosystem.



It’s true that in Android there is a 1: 1 relationship between the SDK and the API, and often these two terms are used synonymously, but it’s important to understand that this is not the same thing.



It’s more correct to say that for each version of Android there is an SDK and an equivalent API, as well as the level of this API.



SDK



It stands for Software Development Kit . Pay attention to the word “kit” (kit) ... it just consists of a set of various tools, libraries, documentation, examples that help developers create, debug and run Android applications. An API is provided with the SDK.



If you open the SDK Manager in Android Studio, you can see more clearly what the Android SDK consists of.



The first tab of the Platform SDK lists the SDKs of each version of Android.



As shown in the image below, the Android 9.0 SDK (also known as Pie) contains:







Overview of the SDK in the Android Studio SDK Manager.



The second tab of the SDK Tools shows other tools that are also part of the SDK but are independent of the platform version. This means that they can be released or updated separately.



API



It stands for Application Programming Interface . It is just an interface, an abstraction layer that provides a link between two different “parts” of software. It works like a contract between a provider (for example, a library) and a consumer (for example, an application).



This is a set of formal definitions, such as classes, methods, functions, modules, constants, which can be used by other developers to write their own code. However, the API does not include an implementation.



API level



The API level is an integer value that uniquely identifies the version of the framework API offered by the Android platform.



Typically, platform framework API updates are designed so that the new version of the API remains compatible with earlier versions, so most of the changes in the new API are additive, and the old parts of the API become obsolete but not deleted.



And now someone might wonder ...



if the Android API does not provide an implementation, and the SDK Manager offers an optional downloadable API source code as part of the SDK, then where is the corresponding implementation?



The answer is simple. On the device.



Let's figure it out ...



From source code to APK file



Typically, an Android project consists of code written by developers using the Android API (application module), as well as some other libraries / dependencies (.jar files, AAR, modules, etc.) and resources.



The compilation process converts code written in Java or Kotlin, including dependencies (one of the reasons to reduce your code!), Into DEX bytecode, and then compresses everything into an APK file along with resources. At this stage, the implementation of the API is not included in the final APK!





Build Process - Android Developers



DEX files and Android Runtime





Android Architecture - Android Developers



Android Runtime is the place where all the dirty work is done and where the DEX files are executed. It consists of two main components:





The version of the API available at this level corresponds to the version of the Android platform on which the application is running.
For example, if Android 9 (Pie) is installed on the actual device, all APIs up to level 28 are available.



If you understand the key points of Android Runtime and what the role of the API is, then it should be easy to understand backward and forward compatibility , as well as the use of compileSdkVersion



, minSdkVersion



and targetSdkVersion



.



compileSdkVersion



This value is only used to tell Gradle which version of the SDK to compile your application with. This allows developers to access all the APIs available up to the API level set for compileSdkVersion



.



Compiling with the latest version of the SDK is highly recommended:





For example, to use SupportLibrary-28.xx



, compileSdkVersion



must also be 28.





Android applications are compatible with new versions of the Android platform, since changes to the API are usually additive, and the old API may become obsolete, but not removed.



This means that direct compatibility is mainly guaranteed by the platform, and when you run the application on a device with a higher level of API than the one specified in compileSdkVersion



, there are no problems at run time, the application will work as expected on newer versions of the platform.



For example:



The application + compileSdkVersion = 26 and the xyz()



API method, introduced in API level 26 , can work on a device with Android 8 Oreo (API level 26).



The same application can work on a device with Android 9 Pie (API level 28), since the API xyz()



method is still available on API level 28.



minSdkVersion



This value indicates the minimum API level at which the application can run. This is a minimum requirement. If not specified, the default value is 1 .



Developers are required to set the correct value and ensure the correct operation of the application up to this API level. This is called backward compatibility .



During development, Lint



also warn developers when they try to use any API below that specified in minSdkVersion



. It is very important not to ignore the warnings and correct them!



To ensure backward compatibility , developers can check the version of the platform at run time and use the new API in newer versions of the platform and the old API in older versions or, depending on the case, use some static libraries that provide backward compatibility.



It is also important to mention that the Google Play Store uses this value to determine whether the application can be installed on a specific device by comparing the version of the device platform with the minSdkVersion



application.



Developers should be very careful when choosing this value, since backward compatibility is not guaranteed by the platform.



Choosing the “right” value for a project is also a business decision, as it affects how large the audience of the application will be. Look at the distribution of platforms .



For example:



The application + compileSdkVersion = 26 + minSdkVersion



= 22 and the xyz()



API method, introduced in Level 26 API, can work on a device with Android 8 Oreo (Level 26 API).



The same application can be installed and run on an older device with Android 5.1 Lollipop (API level 22), where the API method xyz()



does not exist. If the developers did not provide backward compatibility either through runtime checks or through any libraries, then the application will crash as soon as it tries to access the xyz()



API method.



targetSdkVersion



This value indicates the level of API at which the application was developed.



Do not confuse it with compileSdkVersion



. The latter is used only at compile time and makes new APIs available to developers. The first, by contrast, is part of the APK (as well as minSdkVersion



) and changes the behavior of the runtime. This is the way developers can control direct compatibility .



Sometimes there may be some API changes in the base system that can affect the behavior of the application when working in a new runtime environment.



The target application tier includes runtime behavior that is specific to the platform version. If the application is not ready to support these changes to the runtime behavior, it is likely to fail.



A simple example is the Runtime Permission , which was introduced in Android 6 Marshmallow (API level 23).



An application can be compiled using a level 23 API, but have a target level 22 API if it is not yet ready to support the new runtime permission model.



Thus, an application can still be compatible without including new runtime behavior.



In any case, as already mentioned, Google requires applications to meet the new requirements of the target API level, so you should always have high priority to update this value.



Now putting it all together, we see a clear relationship



minSdkVersion ≤ targetSdkVersion ≤ compileSdkVersion







Keep in mind that it is highly recommended that you compile with the latest API level and try to use targetSdkVersion == compileSdkVersion .



Sources






All Articles