Hello. My name is Kirill Rozov, and if you are interested in Android development, then most likely you have heard about the Android ResId Telegram channel with daily news for Android developers.
Modern mobile applications are already quite serious enterprise projects that are developed by hundreds of developers, contain thousands of lines of code and are constantly changing and developing. The process of automating code checking and application work helps to deal with such a huge codebase. Today I will tell you what tools you can use to improve the stability of your project and avoid mistakes, as well as save time for colleagues during a pull request.
Are you developing a project with a small team or alone? Then this article is even more important to you, since you most likely didn’t configure any checks for yourself, and I will tell you why this needs to be done.
Types of code checking
Code analyzers is divided on two types:
- static code analysis (without starting the application)
- code analysis while the application is running
Android development uses statically typed compiled languages: Java and Kotlin. These are important requirements for languages that allow them to analyze code without having to run it, and they can do it right at the time of writing the code. This type of analysis is called static. This makes it easy to run analyzing on any CI and automate checking for simple errors, such as not closing a stream after reading/writing code. The disadvantage of such checks is that if your code deviates from the template embedded in it, then the code will not work or will work incorrectly. Also, such analyzers can’t understand complex code execution scenarios and their effect.
More serious checks of your code can be done by automatically analyzing it while the application is running (dynamic). For example, you can track down memory leaks or problems that occur due to linked libraries. The most famous utility is LeakCanary. The main disadvantage of such tools is the need to run on a real device, which complicates the automatic check for CI, since you need to have connected devices or a device farm.
Code Analysis Tools
IDEA Code Inspections
The first tool that any developer implicitly comes across is the IDE. Modern IDEs are not only syntax highlighting and autocompletion, but also code analysis, error search and other hints. IDEA has many checks for Java and Kotlin, and each new version improves the work of the old checks, and the list is updated with new ones.
The disadvantage of checks from IDEA is that you need IDEA to run them on CI, but now it has become easier with the advent of the Qodana project. You can use a Docker image, integrate a TeamCity plugin, or customize a GitHub application. At the time of this article’s release, Qodana is in development, and nothing is known about its paid-for.
Checkings in Android Studio 4.2
Code Style Checking
How often have you been annoyed that a new developer doesn’t follow the code style of the application? If you don’t have this, then most likely you have already configured utilities that check that the code matches your style.
Checkstyle — analysis of Java code style
Checkstyle is a very powerful and flexible solution that is used to check that a code style is consistent with a team’s standard. Only Java code, which is no longer very relevant for modern Android development, which switched to Kotlin, but it’s very relevant for Backend development where Java is main language. Checkstyle allows you to make a very flexible setting of parameters and describe any requirements for the design of Java code.
Pinterest’s ktlint utility is for checking Kotlin code style. The utility is not as flexible in its parameters as Checkstyle and only allows you to set some parameters. All rules are set in accordance with the Kotlin Coding Convention and Android Kotlin Style Guide, taking into account the settings from the .editorconfig. The utility also allows you to format your Kotlin code. Ktlint is developing slowly and for several years of its existence it has not yet reached a stable release, but it works without problems, and is also constantly updated to support the new version of the language. Unfortunately, sometimes it’s updated with delays, which makes it impossible to fully update the project to a new version of Kotlin.
Another important tool for sharing common coding style between developers is the .editorconfig file. This is a special file that contains code style options and editor plugin settings. You describe the common parameters for all files, and you can also set special values for individual files or for a group of files based on a template. EditorConfig is supported by IDEA and AndroidStudio, and there is also a dedicated plugin.
PMD (formerly Findbugs)
PMD is an extensible static code analyzer with support for many languages, and it can also find «Copy-paste». We are primarily interested in PMD because of Java support, since there is no Kotlin support. PMD is actively developing and gaining momentum, but in the Android world it’s becoming less and less popular due to the massive transition to Kotlin.
Error Prone by Google
Google Error Prone is another static Java code analyzer that will throw compile-time errors if rules are violated. You can also write your own rules and link them separately, or try contributing to the main repository. I have used this tool several times. Have you used it at home? Write in the comments!
Android Lint is a comprehensive analysis of Android projects
Android Lint is the official solution from the Android team for analyzing your Android projects. You can check any file that is in the project: code, resources, AndroidManifest, etc. The advantage of this tool is that analysis can be performed not only in one file, but also between files within the same project. For example, you can read the configuration from the AndroidManifest and see if you need to issue warnings or not.
Android Lint allows you to create your own rules and easily package them together with your libraries as part of the AAR archive, and Android tooling will automatically include them into the project.
This sounds very nice, but there are a few downsides. The main drawback is the speed of work. It can take several tens of minutes to run checks in the entire project, so it’s problematic to run them as part of a pull request. Although Apple Silicon is very powerful, so it can handle it)
Also, the API for writing rules is not final and is constantly changing, although full documentation and descriptions of all the terminology used have appeared recently.
rxlint is a set of Android checks that validate Rxjava
If you are actively using RxJava in your project, then I recommend that you connect this set of checks in addition to Android Lint to avoid errors.
detekt is an analysis of Kotlin code
If you want a static code analysis solution for Kotlin, then Detekt is your choice. The utility is constantly evolving, existing checks are improved and new checks are added. You can enable/disable any check, as well as customize it for yourself. You can also write your own rules and distribute them. For example, in this way ktlint is fully integrated via detekt-format. Detekt has many integrations with today’s popular tools. Its disadvantages include that not all rules work correctly, and some rules don’t work, but there are no tools for analyzing Kotlin code except IDEA and Android Lint checks, so Detekt has become the standard. I recommend that you install the detekt plugin of the same name to integrate Detekt with Android Studio/IDEA.
I told you about many solutions, and it can be very difficult for you to manage all of them and monitor the quality, so you need some kind of high-quality aggregator. Such a tool is SonarQube, which, in addition to its own rules, is able to understand the reports of other tools and add them to a single project report. Their own rules are written wonderfully, and I learned a lot during the development of Android applications in Java thanks to a high-quality description of the causes of the problems and how to fix them.
Sonarqube has a free version that will be enough for Android developers, but you have to use it on your own server or you will have to pay for the version in the cloud. If you have an Open Source project, then you can use the cloud version without restrictions — SonarCloud. You can find an example of analyzing popular Open Source projects here.
The disadvantages of SonarQube include a small number of rules for Kotlin (at the time of this writing this article), as well as the lack of official integration with Android Lint. The third party extension doesn’t add all the rules, which makes the report less useful.
Analysis while the application is running
We’re moving on to utilities that analyze your code while the application is running. I highly recommend that you only enable them during development and that their code doesn’t end up in production builds. The most commonplace way is to check now whether it is an assembly or not, and based on this, initialize the library or not. An advanced way to exclude such code is to include the library only in test assemblies, which will require you to organize the code correctly and put the code into different folders with sources.
Android Strict Mode
StrictMode is a standard tool in the Android SDK that dates back to Android 2.3 and allows you to enable various rules. If the rule is broken, then there will be a reaction that you can control. The reaction can be a message in Logcat, showing a dialog, or an application crash. In later versions, you can set a callback and track the problem in Firebase Crashlytics or similar services to build crashes.
The utility has a huge number of rules that are updated in each version of Android. Their problem is that they are fragmented in the Compat API. I corrected this unfortunate misunderstanding with my library, which, in addition to this, also adds a Kotlin DSL for configuration — StrictModeCompat
If you haven’t heard about LeakCanary yet, then you haven’t thought about how to track memory leaks in your Android application. This wonderful development integrates into your application, shows leaking objects and allows you to create dumps that QA can easily share with you. Everything is done super conveniently and pleasantly. I recommend for integration. It can also be integrated with your crash tracking tool.
Nobody wants the application to slow down, especially for the user to see the ANR dialogue. ANR-WatchDog makes sure that ANRs don’t happen to you, and it allows you to track them back to production. If such problems are found in Logcat, a special error with details will be displayed. You can also send it to Crashlytics or other services.
In the comments, I invite you to talk about your ways of automating issue tracking and maintaining the level of code quality in your projects, as well as the tools you use to do this.