The Android Lint utility is probably one of the most powerful tools in your arsenal that you are not using. In addition to ensuring your app meets its functional requirements by building tests, it’s important that you also ensure your code has no structural problem by running the code through lint.
Despite it’s name, Android Lint is not just a linting tool, it is actually like a full fledged stack analysis framework.
For example, structural issues, such as use of deprecated elements or API calls that are not supported by the target API versions or running a network operation on a UI thread, might lead to code failing to run correctly. Lint can help you clean this up. The same goes if you have XML resource files that contain unused namespaces which take up space and incur unnecessary processing.
In this post, I will be sharing helpful information that will help in
- Understanding Lint
- Improving Lint Performance
- Configuring Lint for better code review
Now, let’s dive in !
Ways to use Lint
You can use Lint in any of these ways:
- In Android Studio
- via Gradle
- As a Standalone tool.
In Android Studio
- On the Fly : Lint is integrated deeply into the Android Studio IDE. It shows error messages or warnings as you type your codes.
- Inspect Code : This is an action in android studio that can keep your coding standard in check by running a batch analysis on your entire project or even a single file . It’s a great way to audit your project for common errors.
To run inspect code
Select project , file or folder > Analyze > Inspect Code
- Run Inspection by name : This is closely related to Inspect Code but with this you can audit your project on a look out for bugs or practices that match a pattern or name. To run inspection by name:
Select project , file or folder > Analyze > Inspection by Name
You can also create custom scope for your inspection. See https://developer.android.com/studio/write/lint for more .
via Gradle
If you’re using Android Studio or Gradle, you can use the Gradle wrapper to invoke the lint
task for your project by entering the following commands from the root directory of your project:
./gradlew lint[flavour][variant] e.g lintDebug or lintStagingDebug
The really good thing about this is that it not only does a batch analysis of your entire project but it also makes a html and xml report.
Standalone Tool
If you’re not using Android Studio or Gradle, you can use the standalone lint tool after you install the Android SDK Tools from the SDK Manager. You can locate the lint tool in the android_sdk/tools/
directory.
To run lint against a list of files in a project directory, use the following command:
lint [flags] <project directory>
To see the full list of flags and command-line arguments supported by the tool, use the following command:
lint --help
Advance Use Cases
Lint is a very powerful tool, no doubt about that. Now that we’ve covered the very basic, let’s dive into advance use cases.
Configuration
The easiest way to see what Lint is capable of doing is to look into Inspections In Android Studio Editor Preferences. Most are enabled by default while some are not. Going through this list will actually give you some insight into writing better codes and it also allows you disable or enable any lint check. Simple way to set up configuration huh? That’s right !
You can specify your lint checking preferences in the lint.xml
file. If you are creating this file manually, place it in the root directory of your Android project.
<?xml version="1.0" encoding="UTF-8"?>
<lint>
<!-- Disable the given check in this project -->
<issue id="IconMissingDensityFolder" severity="ignore" />
<!-- Ignore the ObsoleteLayoutParam issue in the specified files -->
<issue id="ObsoleteLayoutParam">
<ignore path="res/layout/activation.xml" />
<ignore path="res/layout-xlarge/activation.xml" />
</issue>
<!-- Ignore the UselessLeaf issue in the specified file -->
<issue id="UselessLeaf">
<ignore path="res/layout/main.xml" />
</issue>
<!-- Change the severity of hardcoded strings to "error" -->
<issue id="HardcodedText" severity="error" />
</lint>
Another way to configure lint is with Gradle. In build.gradle file, lint can be configure in the linkOptions block.
android{
lintOptions{
// ... lint configurations goes here
}
}
Let’s run through some powerful options:
- Baseline: You can take a snapshot of your project’s current set of warnings, and then use the snapshot as a baseline for future inspection runs so that only new issues are reported. The baseline snapshot lets you start using lint to fail the build without having to go back to address all existing issues first. It’s like giving you a fresh start from old issues.
To create a baseline snapshot, modify your project’s build.gradle
file as follows.
android {
lintOptions {
baseline file("lint-baseline.xml")
}
}
When you first add this line, the lint-baseline.xml
file is created to establish your baseline. From then on, the tool only read the file to determine the baseline. If you want to create a new baseline, manually delete the file and run lint again to recreate it or just change the name of the xml file.
2. warningsAsErrors: Well, this is pretty straight forward. For those that care about clean code, this command is hell bent on making sure you resolve all warnings before the project can build. Tough one right here.
android {
lintOptions {
warningsAsErrors true
}
}
Here are other common lintOptions:
android {
...
lintOptions {
// Turns off checks for the issue IDs you specify.
disable 'TypographyFractions','TypographyQuotes'
// Turns on checks for the issue IDs you specify. These checks are in
// addition to the default lint checks.
enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
// To enable checks for only a subset of issue IDs and ignore all others,
// list the issue IDs with the 'check' property instead. This property overrides
// any issue IDs you enable or disable using the properties above.
check 'NewApi', 'InlinedApi'
// If set to true, turns off analysis progress reporting by lint.
quiet true
// if set to true (default), stops the build if errors are found.
abortOnError false
// if true, only report errors.
ignoreWarnings true
}
}
See lintOptions for more.
On Performance,
- try to avoid checkAllWarning Options. Be very selective in the checks that are turned on.
- Also, avoid running gradle lint task. Be specific !
DO NOT DO THIS./gradlew lintDO THIS INSTEAD./gradlew lintDebug or ./gradlew lintProdRelease (depending on whether you have build variant)
Lint configuration check can be disabled in java and kotlin via @SuppressLint annotations or via attribute in xml (tools:ignore)
// in Java
@SuppressLint("ParserError")
class FeedProvider : ContentProvider() {
// in XML
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
tools:ignore="UnusedResources" >
<TextView
android:text="@string/auto_update_prompt" />
</LinearLayout>
Annotations
Help Lint help you
Annotation gives you powerful way to give Lint hints for specific issues. Let’s run through some of the basic lint annotation command.
Learn more about these annotations here
Writing Custom Lint rules
Android Lint is actually a framework. You can write your own lint checks tailored for your team, project or for practices in your app development. The good thing about this is that it can be shared with your team members and these checks will be observed in their IDE.
Lint Api is currently unstable. Changes might most likely occur in future but it’s definitely for good. So, watch the Android Lint space
A walk through on writing custom lint rules is quite detailed and we will be sharing that in the next post. So, watch this space and let us know if this was helpful.