a Developer’s insight(s) about Android + Gradle
Developers are afraid of gradle because it consumes their valuable time if they sit to fix the issues. Most of the gradle issues arise due to misconfiguration of the versions without having a proper knowledge of gradle. Let’s see how a developer tries to fix a gradle issue…
Developer 1: Hey dude, I am not able to build my android project, I am getting the gradle issue.
Developer 2: Have you tried searching the issue on google?
Developer 1: Yes, I have tried all the possibilities. Copied and pasted all the solutions from google but still, the issue is not resolved.
Developer 2: Ok try Clean build, Rebuild, Invalidate Cache/Restart, Remove your project from the recent project. Try these options one by one (or) together, your issue might get resolved.
This is how we try to solve a gradle issue. Even I am one among the above developers. This is because of the following reasons
- We are not aware of how android studio uses gradle to build the application.
- There is no proper sites or documentation teaching developers, how versions should be configured in gradle to avoid versioning issue.
Gradle has a lot to offer the Android developers, so it’s well worth investing some time into learning gradle. First of all, every developer should understand the key terms of android + gradle.
- SDK Versions
- Android Support Library
- Android Gradle Plugin
- Android Build Tool
A brief description of these terms will offer you some insights into gradle.
Android will release their new Software Development Kit Packages to developers while releasing a new Android OS Version. This enables developers to create applications for the Android platform with the latest released features. Let us see the three sdk versions that play a vital role in compiling and building the app.
- minSdkVersion: This is the lowest android SDK version for your app
- The app cannot be installed in devices with lower API level than minSdk. Example: Suppose app’s `minSdkVersion is 26 — Android Oreo` and if I try to install it in a lower-end device with OS Android Nougat, I cannot install the app.
- Based on your minSdkVersion the Google Play Store decides which device users to show your app.
- The app won’t be even shown in search results in the Play Store app if the user’s device version does not meet the minSdkVersion.
2. compileSdkVersion: It is the version of Android in which you write code. If you choose version 28, you can write code with all the features in API version 28. You have to keep in mind that changing your compileSdkVersion does not change the app’s runtime behavior. By adding compile sdk version you can check the following items.
- You will get hints about the deprecated method, letting you know that something is deprecated in newer API levels, so you can react accordingly.
- This approach also has the benefit of learning what is new and what is old while coding.
- You’ll get all the benefits of new compilation checks on existing code and be ready to use new APIs.
3. targetSdkVersion: This is a message for the android system on which app is running, indicating which API level is the app designed for. This is more like a certification or sign off you are giving to the Android OS that you have tested your app on the version you specify.
Note: minSdkVersion <= targetSdkVersion <= compileSdkVersion
Android Support Library
The Android Support Library is a set of code libraries that provide backward-compatible enhancements of the Android framework. Although the support library started out as providing backward compatibility, later it has evolved into a way of providing additional features like RecyclerView, CardView, Annotations etc. It provides the equal implementation of platform API classes. You can use the Android Support Library for the following purpose.
- Backward-compatible versions of new Android API features. For example, suppose a new feature is introduced in Android api level 27, its corresponding Android Support Library 27.x.x will have methods to handle this new feature gracefully in devices of api level < 27.
- For additional UI elements.
- For features not included in the standard Android framework.
Android Gradle Plugin
Android Gradle plugin is the set of gradle tasks that are specific for building Android apps. After adding the line `apply plugin: ‘com.android.application’ ` in your app’s build.gradle and once sync has been done, you can see several gradle tasks on the extreme right side of Android Studio, under Gradle tab.
To know about the tasks, use the below command in the studio’s terminal
- Windows user: gradlew tasks
- Mac user: ./gradlew tasks
Why Gradle needs Android gradle plugin?
As we know gradle is independent of any platforms, which means gradle is not anyway related to any of the platforms, in our case it is android. Gradle is completely written in groovy scripts, so the android gradle plugin is a mediator which acts as a bridge between Android and Gradle. The android gradle plugin scripts are written in such a way that it can communicate with android tools to complete its job.
Android Build Tools
The tools required to build an android application.
- AAPT2 (Android Asset Packaging Tool) is a build tool that Android Studio and Android Gradle Plugin use to compile and package your app’s resources such as drawables and XML files.
- The dx tool converts Java class files into a .dex (Dalvik Executable) file.
- apksigner allows you to sign APKs.
- Zipalign is an archive alignment tool to optimize the way an APK is packaged. Execution time is minimized for zipaligned applications, resulting in a lesser amount of RAM consumption when running the APK.
Is Gradle is a build system? If so then why android has build tools separately? As an android developer, I have this kind of doubts itching my brain so I started to analyze the gradle little bit deeper and understood the difference between build system and build tool. For easy understanding, I will split the definition of gradle into parts.
Definition Version 1: Gradle is a build automation system.
So you all know the meaning of `build` and `automation`, lets see what `system` means here. System — A set of procedures and routines created to carry out a specific activity. From this let us inherit the second version.
Definition Version 2: Gradle is a set of procedures and routines created to carry out a specific activity.
Now everyone think of your build.gradle files. Let us derive the third and final definition of gradle from the above definition.
Procedure and Routines here means
- Declaring plugins and dependencies.
- Adding repositories to download dependencies.
- Providing android sdk versions that the app should support, compile and target for.
- Mentioning the build tool version that is used to compile and build the app.
Specific activity here means building the application.
Now the final definition for gradle is here for you
Definition 3: Gradle is a set of build procedure and routines that automatically download plugins, dependency libraries required to build an application using android build tools.
So now I think everyone is clear that a build system is different from a build tool.
Hope everyone understands the five key terms of Android + Gradle. As a developer, we have to know how to play with these terms in a correct way to avoid versioning issues. Deciding which version of these terms to use is an art. Since these terms are linked with one another, if any of the versions are wrongly configured will leads to conflicts. I will share you a plan or design that explains how a proper versioning can be achieved.
The above diagram clearly depicts in what order versioning should be done. Will see the flow in detail.
1. Whenever you decided to change your compileSdkVersion, you have to remember that Android Support Library Version and Build Tool Version should also to be updated, so that both the versions should be greater or equal to compileSdkVersion.
Support Library Version & Build Tool Version >= compileSdkVersion
The reason is if you change your compileSdkVersion which means you are going to write code with the features included in this sdk version. So obviously, to provide backward-compatibility you have to update the Support Library Version. In the same way, to compile or build this code with newer features you have to update the Build Tools Version too.
2. If you update the Build Tools Version then you have to update its corresponding Android Gradle Plugin Version also. Check Android Gradle Plugin release notes to know which plugin version supports your build tools.
3. Next one would be the Gradle Versioning. See the table list in the Android Gradle Plugin release notes to know which version of Gradle is required for each version of the Android Gradle Plugin.
4. Android Studio will automatically ask you to update Gradle and Android Gradle Plugin when you update Android Studio IDE or importing a new project into the IDE. I would suggest you to manually update the versions according to your project
Finally, I would like to share a few of my understandings on adding the remote dependencies. As a developer, we should take more care while adding/updating the dependencies. I have seen many developers using the third party libraries without any proper analysis or validation. This might not only cause functionality break but also leads to serious security consequences. so keep the following points in mind while adding or updating a remote dependency.
1. Do a proper validation before using the third party libraries.
2. Some libraries may have their own minSdkVersion so your app’s minSdkVersion must be at least as high as your dependencies’ minSdkVersion.
3. Many of them might hear about Transitive dependency. It is a dependency that allows your project to depend on libraries that depend on other libraries which leads to a dependency tree. To make you more clear I will picturize a scenario here.
If gradle finds out multiple dependencies to the same library but different versions then it has to make a choice. Including different versions of the same library wouldn’t make sense. In such case, gradle by default chooses the newest version (27.0.2) of that library. This might cause runtime crash if any of the old functionality or method which is currently used by the library is removed in the newer version. To avoid this kind of conflicts, always use the same version in both project and its dependencies.
If you found this post useful, it would help others to find it if you could click on the 👏 icon below and also do follow for more articles like this — thanks!