(Top)
1 Lint Command Lint Flags
1.1 General
1.2 Enabled Checks
1.3 Output Options
1.4 Project Options
1.5 Advanced Options (for build system integration)
1.6 Exit Status
2 Lint Gradle Plugin DSL
2.1 Configuring Issues and Severity
2.2 Configuring Output and Reports
2.3 Files to Include
2.4 Other
3 Combining AGP With Newer Lint
3.1 Configuring the Lint Version
3.2 Updating Lint
4 Baselines
4.1 Creating a Baseline
4.2 Customize the baseline
4.3 Baseline warning
5 Performance Tuning
5.1 Use 7.0 and Incremental Lint
5.2 Use the lintDebug
target, not lint
5.3 Only analyze app/leaf modules
5.4 Don't analyze test sources
5.5 Don't use checkAllWarnings
5.6 Use latest version
5.7 Give lint a lot of RAM
5.8 Finding Slow Lint Checks
6 Suppressing Lint Checks
7 Configuring Using lint.xml Files
7.1 XML Syntax
7.2 Nesting & Precedence
7.3 Sample lint.xml file
8 Appendix: Recent Changes
9 Appendix: Environment Variables and System Properties
9.1 Environment Variables
9.1.1 Detector Configuration Variables
9.1.2 Lint Configuration Variables
9.1.3 Lint Development Variables
9.2 System Properties
This chapter inlines all the usage information into a single long book, suitable for printing or reading on a tablet.
Recent Changes
This chapter lists recent changes to lint that affect users of lint. For information about internal improvements and API changes affecting lint check authors, see the API Guide.
8.6
Issue ID | Summary |
---|---|
AccessibilityFocus | Forcing accessibility focus |
AccessibilityScrollActions | Incomplete Scroll Action support |
AccessibilityWindowStateChangedEvent | Use of accessibility window state change events |
CredentialDependency | credentials-play-services-auth is Required |
PictureInPictureIssue | Picture In Picture best practices not followed |
SimilarGradleDependency | Multiple Versions Gradle Dependency |
UnclosedTrace | Incorrect trace section usage |
8.4
Issue ID | Summary |
---|---|
BuildListAdds | Missing add call in buildList |
PublicKeyCredential | Creating public key credential |
SecretInSource | Secret in source code |
LintBaselineFixed | Baseline issues fixed |
LintBaseline
issue was reporting two different types of issues:
Since these are separate problems and you may want to configure one
and not the other to be a warning or an error, the LintBaseline
issue id is now only used for the first type of issue, and the second
one is reported under a new issue ID, LintBaselineFixed
. If you had
previously suppressed LintBaseline
in order to remove both of these
reports, you'l need to also suppress LintBaselineFixed
.
8.3
Issue ID | Summary |
---|---|
ActivityIconColor | Ongoing activity icon is not white |
SelectedPhotoAccess | Behavior change when requesting photo library access |
UseSdkSuppress | Using @SdkSuppress instead of @RequiresApi |
WrongCommentType | Wrong Comment Type |
8.2
Issue ID | Summary |
---|---|
ForegroundServicePermission | Missing permissions required by foregroundServiceType |
ForegroundServiceType | Missing foregroundServiceType attribute in manifest |
IntentWithNullActionLaunch | Unsafe intent launched with no action set |
MutableImplicitPendingIntent | Mutable Implicit PendingIntent is disallowed |
PlaySdkIndexGenericIssues | Library has issues in SDK Index |
StartActivityAndCollapseDeprecated | TileService.startActivityAndCollapse(Intent) is deprecated |
TilePreviewImageFormat | Tile preview is not compliant with standards |
WearBackNavigation | Wear: Disabling Back navigation |
WearMaterialTheme | Using not non-Wear MaterialTheme in a Wear OS project |
WearPasswordInput | Wear: Using password input |
WearRecents | Wear OS: Recents and app resume |
WearSplashScreen | Wear: Use SplashScreen library |
8.1
Issue ID | Summary |
---|---|
NoOp | Finds leftover code constructs which have no side effect or purpose |
UnspecifiedRegisterReceiverFlag | Missing registerReceiver() exported flag |
UnsafeIntentLaunch | Launched unsafe Intent |
UnsafeImplicitIntentLaunch | Implicit intent matches an internal non-exported component |
ReportShortcutUsage | Shortcut usage should be reported |
UseTomlInstead | Mixing and matching Gradle build file and TOML dependencies |
KaptUsageInsteadOfKsp | Using kapt where KSP would also be available |
BomWithoutPlatform | BOM artifact added as a dependency instead of as a platform |
ProviderReadPermissionOnly | Provider with readPermission only and implemented write APIs |
MutableImplicitPendingIntent | Mutable implicit PendingIntent is disallowed |
(The NoOp
and UnsafeImplicitIntentLaunch
lint checks are
currently disabled by default.)
8.0
Issue ID | Summary |
---|---|
ChromeOsOnConfigurationChanged | ChromeOS performance checks in onConfigurationChanged() |
SetAndClearCommunicationDevice | Missing clearCommunicationDevice() after set |
7.4
Issue ID | Summary |
---|---|
PermissionNamingConvention | Custom permissions not following naming convention |
KnownPermissionError | Well-known permission errors, e.g. android:permission="true" |
SystemPermissionTypo | Usage of permissions that look like system permissions, but have typos |
CustomPermissionTypo | Usage of permissions that look like custom permissions from the same project, but have typos |
ReservedSystemPermission | Accidental redefining of a framework permission, or usage of the andriod. prefix |
GestureBackNavigation | Usage of KeyEvent.KEYCODE_BACK |
UnusedTranslation | Unused translation, not declared in localeConfig |
NotificationPermission | Notifications Without android.permission.POST_NOTIFICATIONS |
MonochromeLauncherIcon | Monochrome icon is not defined |
PlaySdkIndexNonCompliant | Library has policy issues in SDK Index |
TileProviderPermissions | TileProvider does not set permission |
SquareAndRoundTilePreviews | TileProvider does not have round and square previews |
InternalInsetResource | Using internal inset dimension resource |
BinderGetCallingInMainThread | Incorrect usage of getCallingUid() or getCallingPid() |
--offline
flag passed to Gradle, and will refrain
from making network calls for checks that normally do (such as
AppLinksAutoVerify
).7.3
Issue ID | Summary |
---|---|
SuspiciousIndentation | Flags suspiciously indented code |
StringFormatTrivial | Avoid trivial conversions in String.format |
WearableActionDuplicate | Duplicate watch face configurations |
EmptySuperCall | Invoking super. on @EmptySuper method |
OpenForTesting | Overriding @OpenForTesting outside tests |
DeprecatedSinceApi | Calling deprecated SDK backport methods |
ReturnThis | Not returning “this” from @ReturnThis methods |
KotlinNullnessAnnotation | Using nullability annotations in Kotlin |
MissingInflatedId | ID not found in inflated resource |
NotificationId0 | Notification Id is 0 |
android.experimental.lint.missingBaselineIsEmptyBaseline=true
in
gradle.properties
, and then run the new task updateLintBaseline
to create or update baselines.7.2
Issue ID | Summary |
---|---|
AssertionSideEffect | Assertions that have side effects |
BidiSpoofing | Misleading bidirectional Unicode strings |
MotionLayoutMissingId | Views inside MotionLayout require an id |
UastImplementation | Avoid UAST implementation classes |
7.1
VisibleForTests
check flagging additional
usages of test-only APIs outside of tests.
Issue ID | Summary |
---|---|
FileEndsWithExt | Flags suspicious usages of File.endsWith(extension) |
DataExtractionRules | Missing data extraction rules |
RedundantLabel | Redundant label on activity in manifest |
DiscouragedApi | Using APIs annotated with @Discouraged |
ViewBindingType | Validation for tools:viewBindingType |
AppBundleLocaleChanges | Handling runtime locale changes |
Issue ID | Summary |
---|---|
MissingTranslation | Now checks for missing translations of plurals |
WrongConstant | Now has quickfixes to replace with constants |
CheckResult | Now also runs in unit tests |
MediaCapabilities
since its advice is no longer the
recommended practice.7.0
Issue ID | Summary |
---|---|
AnnotateVersionCheck | Annotate SDK_INT checks |
CoarseFineLocation | Cannot use ACCESS_FINE_LOCATION without ACCESS_COARSE_LOCATION |
CustomSplashScreen | Application-defined Launch Screen |
CustomX509TrustManager | Implements custom TLS trust manager |
HighSamplingRate | High sensor sampling rate |
IntentFilterExportedReceiver | Unspecified android:exported in manifest |
LaunchActivityFromNotification | Notification Launches Services or BroadcastReceivers |
LeanbackUsesWifi | Using android.hardware.wifi on TV |
MediaCapabilities | Media Capabilities property not specified |
NotificationTrampoline | Notification Trampolines |
NotifyDataSetChanged | Invalidating All RecyclerView Data |
TileProviderPermissions | TileProvider does not set permission |
TrustAllX509TrustManager | Insecure TLS/SSL trust manager |
UnspecifiedImmutableFlag | Missing PendingIntent mutability flag |
WatchFaceEditor | Watch face editor must use launchMode=“standard” |
WebViewClientOnReceivedSslError | Proceeds with the HTTPS connection despite SSL errors |
IntentFilterUniqueDataAttributes | Data tags should only declare unique attributes |
lint
task to the default variant's
lint task instead of running it across all variants and accumulating
results. This is much faster, is usually what you want, and now the
target name will not change based on whether the project has product
flavors, so you can start just running ./gradlew :app:lint
instead
of ./gradlew :app:lintDebug
or :app:lintProDebug
etc.
Furthermore, the lintOptions
block is now just named lint
instead.
4.2
Usage: lint
flags
When using lint from within Gradle, see the Lint Gradle Plugin DSL options instead.
--help
This message.
--help
topicHelp on the given topic, such as “suppress”.
--list
List the available issue id's and exit.
--version
Output version information and exit.
--exitcode
Set the exit code to 1 if errors are found.
--show
List available issues along with full explanations.
--show
idsShow full explanations for the given list of issue id's.
--generate-docs
Generates documentation for all the lint checks. This flag cannot be combined with other lint flags, and it has its own sub-flags. Invoke on its own to see what they are.
--fatalOnly
Only check for fatal severity issues
--apply-suggestions
Apply suggestions to the source code (for safe fixes)
--abort-if-suggestions-applied
Set the exit code to an error if any fixes are applied
You can also pass in directories for files to be analyzed. This was
common many years ago when project metadata tended to be stored in
simple .classpath
files from Eclipse; these days, you typically
will pass it a --lint-model
or --project
description instead.
--disable
listDisable the list of categories or specific issue id's. The list should be a comma-separated list of issue id's or categories.
--enable
listEnable the specific list of issues. This checks all the default issues plus the specifically enabled issues. The list should be a comma-separated list of issue id's or categories.
--check
listOnly check the specific list of issues. This will disable everything and re-enable the given list of issues. The list should be a comma-separated list of issue id's or categories.
--fatal
listSets the default severity of the given issue to fatal
--error
listSets the default severity of the given issue to error
--warning
listSets the default severity of the given issue to warning
--info
listSets the default severity of the given issue to info
-w,
—nowarnOnly check for errors (ignore warnings)
-Wall
Check all warnings, including those off by default
-Werror
Treat all warnings as errors
--config
filenameUse the given configuration file to determine whether issues are enabled or disabled. If a project contains a lint.xml file, then this config file will be used as a fallback.
--override-config
filenameLike —config, but instead of being a fallback, this configuration overrides any local configuration files
--baseline
Use (or create) the given baseline file to filter out known issues.
--update-baseline
Updates the baselines even if they already exist
--remove-fixed
Rewrite the baseline files to remove any issues that have been fixed
--write-reference-baseline
Writes the current results, including issues that were filtered from the input baseline if any. Does not set the exit code to indicate that the baseline is created the way —baseline would. Implies —update-baseline and —continue-after-baseline-created.
--missing-baseline-is-empty-baseline
Treat a missing baseline file as an empty baseline file. In most cases, this means that if the baseline file does not exist, a new one will not be created. But in the case when —update-baseline is also used and there are lint issues, a new baseline file will be created, and the lint issues will be written to it.
--baseline-omit-line-numbers
Omit line numbers when writing out the baseline file
--allow-suppress
Whether to allow suppressing issues that have been explicitly registered as not suppressible.
--restrict-suppress
Opposite of —allow-suppress: do not allow suppressing restricted issues
--skip-annotated
Comma separated list of annotations (by fully qualified name) which indicate that lint should ignore this compilation unit (only allowed on top level classes and files)
--quiet
Don't show progress.
--stacktrace
Print full stacktrace for internal errors.
--fullpath
Use full paths in the error output.
--showall
Do not truncate long messages, lists of alternate locations, etc.
--nolines
Do not include the source file lines with errors in the output. By default, the error output includes snippets of source code on the line containing the error, but this flag turns it off.
--html
filenameCreate an HTML report instead. If the filename is a directory (or a new filename without an extension), lint will create a separate report for each scanned project.
--url
filepath=urlAdd links to HTML report, replacing local path prefixes with url prefix. The mapping can be a comma-separated list of path prefixes to corresponding URL prefixes, such as C:\temp\Proj1=http://buildserver/sources/temp/Proj1. To turn off linking to files, use —url none
--xml
filenameCreate an XML report instead.
--sarif
filenameCreate a SARIF report instead.
--text
filename Write a text report to the given file. If the filename is just
stdout
(short for standard out), the report is written to the
console.
--resources dir | Add the given folder (or path) as a resource directory for the project. Only valid when running lint on a single project. |
--sources dir | Add the given folder (or path) as a source directory for the project. Only valid when running lint on a single project. |
--classpath dir | Add the given folder (or jar file, or path) as a class directory for the project. Only valid when running lint on a single project. |
--libraries dir | Add the given folder (or jar file, or path) as a class library for the project. Only valid when running lint on a single project. |
--compile-sdk-version version | Use the given compileSdkVersion to pick an SDK target to resolve Android API call to |
--sdk-home dir | Use the given SDK instead of attempting to find it relative to the lint installation or via $ANDROID_SDK_ROOT |
--jdk-home dir | Use the given JDK instead of attempting to find it via $JAVA_HOME or java.home |
--java-language-level level | Use the given version of the Java programming language |
--kotlin-language-level level | Use the given version of the Kotlin programming language |
--project
fileUse the given project layout descriptor file to describe the set of available sources, resources and libraries. Used to drive lint with build systems not natively integrated with lint.
--lint-model
pathAlternative to —project which defines the project layout
--variant
nameThe name of the variant from the lint model to use for analysis
--lint-rule-jars
pathOne or more .jar files to load additional lint checks from
--analyze-only
Perform only analysis, not reporting, of the given lint model
--report-only
Perform only reporting of previous analysis results
--path-variables
variablesPath variables to use in internal persistence files to make lint results cacheable. Use a semi-colon separated list of name=path pairs.
--describe-suggestions
fileDescribes all the quickfixes in an XML file expressed as document edits — insert, replace, delete
--client-id
Sets the id of the client, such as “gradle”
--client-name
Sets the display name of the client, such as “Android Gradle Plugin”
--client-version
Sets the version of the client, such as “7.1.0-alpha01”
--offline
Whether lint should attempt to stay offline
0 | Success. |
1 | Lint errors detected. |
2 | Lint usage. |
3 | Cannot clobber existing file. |
4 | Lint help. |
5 | Invalid command-line argument. |
6 | A new baseline file was created. |
7 | Quickfixes were applied. |
Lint is integrated into three Gradle plugins:
The com.android.lint
plugin is the “standalone” lint Gradle plugin
which can be applied to any Kotlin or Java Gradle project. To configure
this project, use a lint
block to configure it, like this:
apply plugin: 'kotlin'
apply plugin: 'com.android.lint'
lint {
htmlOutput = file("lint-report.html")
textReport = true
}
lintOptions
until 7.0. You can
still refer to it as lintOptions
, but this was cleaned up as part
of the Android Gradle Plugin's overhaul of its DSL in 7.0. Another
7.0 change is that the lint
task no longer runs lint on all
variants, but just the default variant — so you no longer have to
run :app:lintDebug
for example — you can simply run :app:lint
.
The com.android.library
and com.android.application
plugins for
Android development bundles in the lint support. They register a lint
task for each variant, as well as a task named lint
which runs the
default variant's lint task.
To configure lint for Android, place the lint
block within the
android
block:
android {
lint {
htmlOutput = file("lint-report.html")
textReport = true
}
}
ignoreWarnings
true or falseWhether lint should only report errors. False by default.
checkAllWarnings
true or falseWhether lint should check all issues, including those that are marked off by default. False by default.
warningsAsErrors
true or falseWhether lint should treat all warnings as errors. False by default.
disable
issue-listList of issue id's that lint should ignore.
Example: disable 'TypographyFractions','TypographyQuotes'
.
enable
issue-listList of issues disabled by default that lint should enable.
Example: enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
.
checkOnly
issue-list If any issues are listed as checkOnly
, then all other issues
are disabled and only those specific issues will be analyzed.
Example: checkOnly 'NewApi', 'InlinedApi'
.
fatal
issue-listSets the severity of the given issues to “fatal” (which means they will be checked during release builds (even if the lint target is not included).
Example: fatal 'NewApi', 'InlinedApi'
error
issue-listSets the severity of the given issues to error.
Example: error 'Wakelock', 'TextViewEdits'
warning
issue-listSets the severity of the given issues to warning.
Example: warning 'ResourceAsColor'
ignore
issue-listSets the severity of the given issues to ignore (same as disabling the check).
Example: ignore 'ResourceAsColor'
informational
issue-listSets the severity of the given issues to informational, which is basically a tip.
Example: informational 'StopShip'
absolutePaths
true or falseWhether lint should include full paths to files in the error reports. If false, paths will be made relative to each module directory. True by default.
noLines
true or falseWhether lint should include showing snippets of the source code along with underlines to show the line of code containing the problem. False by default (note the negated name of the flag).
showAll
true or falseWhether lint should show all locations (for issues that have multiple locations, such as showing each duplicate declaration of a resources), whether it should not truncate lists, etc.
explainIssues
true or falseWhether lint should include a full issue explanations paragraphs in the text error output. Note that this only applies for text reports; HTML and XML reports will always contain explanations. False by default.
textReport
true or false Whether lint should generate a text report. If you don't specify a
location using textOutput
, lint will default to
lint-results-
$variant.txt
in $module/build/reports/, such as
app/build/reports/lint-results-debug.txt`.
textOutput
file or 'stdout'
or 'stderr'
Where lint should write its text output; either a file, or one of
the two magic strings stdout
or stderr
, which writes to the
standard output or standard error streams respectively. In recent
versions of lint, this will also imply textReport true
.
Example: textOutput file(“$buildDir/reports/lint-results.txt”)
xmlReport
true or false Whether lint should generate an XML report. If you don't specify a
location using xmlOutput
, lint will default to
lint-results-
$variant.xml
in $module/build/reports/, such as
app/build/reports/lint-results-debug.xml`.
xmlOutput file("$buildDir/reports/lint-report.xml")
Where lint should write its XML report. In recent versions of lint,
this will also imply xmlReport true
.
Example: xmlOutput file("$buildDir/reports/lint-results.xml")
htmlReport
true or false Whether lint should generate an HTML report, with issue explanations,
code snippets, etc. If you don't specify a location using
htmlOutput
, lint will default to lint-results-
$variant.html
in $module/build/reports/, such as
app/build/reports/lint-results-debug.html`.
htmlOutput
file Where lint should write its HTML report;. In recent versions of lint,
this will also imply htmlReport true
. See also the variables
chapter for some flags to configure the HTML
report.
Example: htmlOutput file(“$buildDir/reports/lint-results.html”)
sarifReport
true or false Whether lint should generate a
SARIF
report for use by for example GitHub. If you don't specify a location
using sarifOutput
, lint will default to
lint-results-
$variant.sarif
in $module/build/reports/, such as
app/build/reports/lint-results-debug.sarif`.
sarifOutput
file Where lint should write its HTML SARIF. In recent versions of lint,
this will also imply sarifReport true
.
Example: sarifOutput file("$buildDir/reports/lint-report.sarif.json")
quiet
true or falseWhether lint should limit its diagnostic output. False by default.
checkGeneratedSources
true or falseNormally lint will skip generated sources, but you can turn it on with this flag. False by default.
checkTestSources
true or falseNormally most lint checks are not run on test sources (except the checks dedicated to looking for mistakes in unit or instrumentation tests, unless ignoreTestSources is true). You can turn on normal lint checking in all sources with this flag. False by default.
ignoreTestSources
true or false Like checkTestSources
, but tells lint to always skip analyzing
tests — meaning that it also ignores checks that have explicitly
asked to look at test sources, such as the unused resource check.
False by default.
checkDependencies
true or falseNormally lint will analyze all dependencies along with each module; this ensures that lint can correctly (for example) determine if a resource declared in a library is unused; checking only the library in isolation would not be able to identify this problem. It also gives you a single cumulative report for the entire project, which is easier to digest. However, in older versions of lint this led to performance problems. False by default, but will soon switch to true by default.
baseline
fileConfigures a baseline. The first time lint is run, and the baseline file does not exist, it will record all the current violations into this file (which can be checked into version control). On subsequent runs, only newly introduced issues (not found in the baseline) will be reported.
Example: baseline file("lint-baseline.xml")
lintConfig
file Sets a lint XML file to use as a fallback
configuration. Avoid calling this file lint.xml
to avoid
ambiguity, since those files are automatically loaded.
Example: lintConfig file("default-lint.xml")
abortOnError
true or falseIf true, stops the Gradle build if one or more errors are found. True by default.
checkReleaseBuilds
true or false If true, include lint analysis in release builds (such as
assembleRelease
), but limited to issues with severity configured to
be fatal
, and abort the build if any fatal issues are found (unless
abortOnError
is set to false). True by default.
DataFlowAnalyzer
received a number of really important fixes
in 7.0, so if you are testing with older versions of lint, some of
the features described above (such as proper support for Kotlin
scoping functions) will not work correctly.Lint is integrated with the Android Gradle plugin; when you run lint from the command line or on your CI server, it will first build all the necessary artifacts, which involves running various optional Gradle plugins, and so on.
Updating the Gradle plugin that you're using to build your project is not always possible:
However, lint is in active development, with new checks being added, existing checks being enhanced and extended, and false positive and false negative bugs getting fixed. You'll almost always be better off running the latest version of lint, including preview versions.
As of AGP 7.0, it's possible to use a newer version of lint in
conjunction with AGP. The way this works is that you tell AGP which
version of lint you want to run, and when you run the lint
target, it
will first build all the necessary artifacts using the current version
of AGP and build scripts. Then it will invoke the newer version of
lint, passing in a bunch of state for lints purposes, and the newer
lint will then analyze the code and produce its report.
In gradle.properties
, add a property declaration like this:
android.experimental.lint.version = 7.1.0-beta01
That's all there is to it. Now running ./gradlew :app:lint
will build
the codebase using your AGP version configured in build.gradle
, such
as 7.0.0, and then the lint analysis and reporting will use version
7.1.0-beta01.
Provided the GradleDependency
issue is enabled, lint will check your
gradle.properties
file and warn you if there is a newer version of
lint available than the one you're pointing to:
gradle.properties:2: Warning: Newer version of lint available: 7.1.0-alpha04 [GradleDependency]
android.experimental.lint.version = 7.0.0-rc01
----------
0 errors, 1 warnings
There is also a quickfix in the IDE to perform this update.
Normally, the GradleDependency
warning will only suggest updating to
a newer version that is a preview if the current dependency is a
preview. However, for using the unbundled lint version, lint will
always suggest using previews. If you for some reason want to limit
yourself to stable versions, such as 8.0.0 while still building with
7.0.0, you can suppress the warning like this:
#noinspection GradleDependency
android.experimental.lint.version=8.0.0
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 and address all existing issues first.
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 tools 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.
Then, run lint from the IDE (Analyze > Inspect Code) or from
the command line as follows. The output prints the location of the
lint-baseline.xml
file. The file location for your setup might be
different from what is shown here.
$ ./gradlew lintDebug
...
Wrote XML report to file:///app/lint-baseline.xml
Created baseline file /app/lint-baseline.xml
Running lint records all of the current issues in the
lint-baseline.xml
file. The set of current issues is called the
baseline, and you can check the lint-baseline.xml
file into version
control if you want to share it with others.
If you want to add some issue types to the baseline, but not all of them, you can specify the issues to add by editing your project's build.gradle, as follows.
android {
lintOptions {
check 'NewApi', 'HandlerLeak'
baseline file("lint-baseline.xml")
}
}
After you create the baseline, if you add any new warnings to the codebase, lint lists only the newly introduced bugs.
When baselines are in effect, you get an informational warning that tells you that one or more issues were filtered out because they were already listed in the baseline. The reason for this warning is to help you remember that you have configured a baseline, because ideally, you would want to fix all of the issues at some point.
This informational warning does not only tell you the exact number of errors and warnings that were filtered out, it also keeps track of issues that are not reported anymore. This information lets you know if you have actually fixed issues, so you can optionally re-create the baseline to prevent the error from coming back undetected.
Lint tends to get slower for every release. There's a reason for that: It keeps checking more and more things (as of 7.0 canary we're up to around 400 separate issues), and existing issues are often made more complex as well, doing deeper flow and data analysis, and occasionally there are new features which also add costs, such as baselines, Kotlin analysis, etc. And this is all compounded by the codebases lint is getting run on also growing bigger and bigger, and being broken up into more and more modules.
This chapter provides some tips on how to improve the performance of lint on CI servers.
In 7.0, lint will finally be capable of running incrementally across modules, meaning that if you change code in just one module, lint will only have to rerun analysis on modules downstream from that module. With large projects with many modules, this should be a significant improvement.
To use this:
We are working on making the state files used by this mechanism path relative such that this facility will also work for Gradle's remote cache; once that's done, this will work for clean builds as well.
lintDebug
target, not lint
If you run ./gradlew tasks
you'll see that there's a lint
task, and
you may be tempted to run it. But lint also adds specific tasks for
each variant. For example, if you only have “debug” and “release”
variants (e.g. you haven't defined any product flavors or additional
build types), lint will create 3 targets:
lint
lintDebug
lintRelease
If you have defined additional build types or product flavors, you can
end up with many more of these — lintFreeDebug
, lintProDebug
,
lintFreeBeta
, lintProBeta
, etc.
Don't configure your CI job to run the lint
task; pick a specific
variant instead, such as lintDebug
. The reason this is so
important, is that what the lint
task really does is run lint over
and over again, for each variant, and then it collates the results in
the end! It combines all the errors it found, and shows which specific
variants every error applies to, unless it applies to all (which is
nearly always the case).
The rationale for this behavior is that you could have a
variant-specific issue; for example, you may have a resource file which
is only present in a variant-specific source set (such as
src/debug/res/values
), so the general lint target checks everything.
Of course, you're probably only shipping your release variant, so you
could limit yourself to just running lintRelease
and you're not going
to miss much.
lintDebug
it's probably more
accurate to run lintRelease
. However, unless you're doing anything
variant specific, it's unlikely that this matters, and running
lintRelease
can take significantly longer since it performs more
build time optimizations.
If you have lots of variants this makes a huge difference; with 7
variants, lint
will take ~7x longer than lintDebug
!! (modulo some
minor caching)
lint
target such that it is just an alias for lintDebug
, so once you
update to 7.0 this is no longer a problem.If you have divided your project into many smaller modules — a number of libraries and just a couple of app modules — it's much better to
To do this, first add this to your app module's build.gradle file:
android {
...
lintOptions {
...
checkDependencies true
...
}
}
Then instead of running ./gradlew lintDebug
, run ./gradlew
:app:lintDebug
.
Since you've turned on check-dependencies mode, running lint on the app module will also run it on all the dependent modules the app depends on — e.g. all the libraries. But this should also make things run a lot faster, since it's a single lint invocation, where lint shares a lot more computation (such as symbol resolution in the SDK and various shared libraries, etc).
checkDependencies true
will also cause lint to analyze
Kotlin-only or Java-only modules, which the normal ./gradlew
lintDebug
approach will not do, since that just invokes lint on
modules that apply the Android plugins. This is actually a good
thing since that code does get included in your Android app and lint
has a number of checks that are relevant for that code. But note
that this analysis isn't free, so it's technically possible that in
some cases (if you have a lot of these modules relative to the
number of Android modules) lint will not actually run faster with
checkDependencies true
. However, for this scenario it's probably a
change you want to make anyway.
This isn't just a good idea from a performance perspective; you'll also
get more accurate results. For example, the unused resource analysis
will now correctly know whether a resource defined in a library is
consumed by the app module; that doesn't happen when you run lint first
on the library, and later on just the app, which is what happens when
you run ./gradlew lintDebug
. As a bonus you'll also get a single HTML
report containing all the results from your codebase, instead of having
to hunt around the tree for all the various reports and look at each
one separately.
Lint has two flags controlling what to do about test sources:
checkTestSources
and ignoreTestSources
. These mean different things.
The checkTestSources
option controls whether lint should run all the
normal checks on the test sources. This is already off by default, so
there's really no performance reason to tweak it. The only reason you'd
turn this on is if you really want to make sure your test sources are
pristine as well. The ignoreTestSources
option on the other hand
controls whether lint should really ignore all test sources. Even if
lint doesn't run normal checks on the test sources, it still has to
include them in analysis for some of the regular lint checks for
production code. For example, what if you have a resource which is only
referenced from a test; do you then want to flag this as unused when
the test is still referencing it?
Add the following to your app module's build.gradle
file to tell lint
to completely ignore your test sources, which should help lint run
faster since (for well tested code) this can help skip a lot of code
analysis and type resolution:
android {
...
lintOptions {
...
ignoreTestSources true
...
}
}
Lint has a checkAllWarnings
option you can use to turn on checking of
all warnings, including those that are off by default. This flag is off
by default, but some developers turn it on (“because I want all the
tips I can get” is what I heard from one developer).
Be careful doing that, because some of the disabled checks are slow,
and some have a lot of false positives which is why they're off by
default but available if you really want to audit for one specific
problem. (In older versions this would also turn on the
WrongThreadInterprocedural
check, which is particularly expensive,
though in recent versions we've specifically exempted this check from
checkAllWarnings
.)
Try using the latest versions of lint (the Android Gradle plugin), as well as of Gradle — even if that means using a canary version. Yes, by all means, for your production builds use a stable version of the Gradle plugin to build your release APK/bundle, but for your CI server, consider running the latest preview version of lint, since generally those versions will have the most up to date fixes. (Yes, regressions happen and canaries go through less testing, but in general lint has really good coverage so regressions do not happen very often.)
This one is kind of obvious, but lint (especially the code analysis part) is really memory hungry; it does a lot of the same work as a compiler, except that it also hangs on to a lot more data (e.g. the full ASTs with whitespace and comments etc). Explore bumping up the memory given to the Gradle daemon significantly to see if it helps bring down the overall analysis time.
This is especially important if you happen to run many lint jobs in parallel! If you follow the advice above (where you're running a single lint job with recursive dependencies on the app module) this is less likely to happen, but I've seen various thread dumps from users asking about performance where there was 16-20 concurrent separate lint jobs running in the Gradle daemon, and each one requires a lot of memory; these separate lint job threads are not sharing data.
One user reported this result:
I have a very large project (with over 2000 classes) and giving lint more memory had a huge effect:
./gradlew -Dorg.gradle.jvmargs=-Xmx2g app:lintDebug
takes 25m 18s
./gradlew -Dorg.gradle.jvmargs=-Xmx8g app:lintDebug
takes 8m 57s!
We have a tool we use to try to attribute the time spent during analysis to individual lint checks. When analysis is taking longer than expected, we run this tool to see if any of the lint checks are misbehaving. Here's some sample output:
$ ./gradlew lintDebug -no-daemon -Dorg.gradle.jvmargs="..."
BUILD SUCCESSFUL in 10s
15 actionable tasks: 1 executed, 14 up-to-date
Lint detector performance stats:
total self calls
LintDriver 3709 ms 1302 ms 2821
TopDownAnalyzerFacadeForJVM 2121 ms 2121 ms 6
IconDetector 81 ms 81 ms 257
OverdrawDetector 51 ms 51 ms 36
InvalidPackageDetector 34 ms 34 ms 51744
GradleDetector 20 ms 20 ms 94
LocaleFolderDetector 11 ms 11 ms 986
RestrictToDetector 11 ms 11 ms 19
ApiDetector 11 ms 11 ms 1255
PrivateResourceDetector 10 ms 10 ms 422
[...]
Here you can see that InvalidPackageDetector
is taking up an
unreasonable amount of time. And this is actually real output from an
earlier version of lint where we tracked down a real problem in that
detector.
You can read more about this tool in this post.
If you see a suspicious check, you can try to disable its issues (unless you find their value is worth the cost; after all, real world bugs are typically more expensive than server compute cycles). But don't forget to also report the bug to the lint check author!
Lint errors can be suppressed in a variety of ways:
@SuppressLint
annotation in the Java code
tools:ignore
attribute in the XML file
build.gradle
file,
as explained below
lint.xml
configuration file in the project
lint.xml
configuration file passed to lint
via the --config
flag
--ignore
flag passed to lint
To suppress a lint warning with an annotation, add
a @SuppressLint("id")
annotation on the class, method
or variable declaration closest to the warning instance
you want to disable. The id can be one or more issue
id's, such as "UnusedResources"
or {"UnusedResources",
"UnusedIds"}
, or it can be "all"
to suppress all lint
warnings in the given scope.
You can also use @Suppress
in Kotlin or @SuppressWarnings
in Java.
To suppress a lint warning with a comment, add
a //noinspection id
comment on the line before the statement
with the error.
To suppress a lint warning in an XML file, add a
tools:ignore="id"
attribute on the element containing
the error, or one of its surrounding elements. You also
need to define the namespace for the tools prefix on the
root element in your document, next to the xmlns:android
declaration:
xmlns:tools="http://schemas.android.com/tools"
To suppress a lint warning in a build.gradle
file, add a
section like this:
android {
lintOptions {
disable 'TypographyFractions','TypographyQuotes'
}
}
Here we specify a comma separated list of issue id's after the
disable command. You can also use warning
or error
instead
of disable
to change the severity of issues.
To suppress lint warnings with a configuration XML file,
create a file named lint.xml
. See the
lint.xml configuration document
for more details.
To suppress lint checks from the command line, pass the
--ignore
flag with a comma separated list of ids to be suppressed, such as:
$ lint --ignore UnusedResources,UselessLeaf /my/project/path
For more information, see https://developer.android.com/studio/write/lint.html#config
In addition to configuring lint with command line flags or Gradle DSL
options, you can also create XML files named lint.xml
, which lint
will look for automatically.
Like .gitignore
files, these can be nested, so you can for example
create a lint.xml
file which sets the severity of an issue to error,
but then in a specific subfolder change the severity to be just a
warning.
This chapter describes the syntax of lint.xml
files.
The root tag is always <lint>
, and it can contain one or more
<issue>
elements. Each
id
: The issue id the following configuration applies
to. Note that this can be a comma separated list of multiple id's, in
which case the configuration applies to all of them. It can also be
the special value “all”, which will match all issue id's. And when
configuring severity, the id is also allowed to be a category, such
as “Security”.
in
: Specifies that this configuration only applies when lint
runs in the given hosts. There are predefined names for various
integrations of lint; “gradle” refers to lint running in the Gradle
plugin; “studio” refers to lint running in the IDE, “cli” refers to
lint running from the command line tools “lint” binary, etc. Like
with id's, this can be a comma separated list, which makes the rule
match if the lint host is any of the listed hosts. Finally, note that
you can also add a “!” in front of each host to negate the check. For
example, to enable a check anywhere except when running in Studio,
use in="!studio"
.
In addition, the
<ignore path="...">
: Specifies a path to ignore. Can contain the
globbing character “*” to match any substring in the path.
<ignore regexp="...">
: Specifies either a regular expression to
ignore. The regular expression is matched against both the location of
the error and the error message itself.
<option name="..." value="...">
: Specifies an option value. This can
be used to configure some lint checks with options.
Finally, on the root lintJars
(a list of jar files containing custom
lint checks, separated by a semicolon as a path separator), and
flags like warningsAsErrors, checkTestSources, etc (matching most
of the flags offered via the lintOptions block in Gradle files).
You can specify configurations for “all”, but these will be
matched after an exact match has been done. E.g. if we have
both <issue id="all" severity="ignore">
and <issue id="MyId" severity="error">
, the severity for MyId
will be “error” since
that's a more exact match.
The lint.xml files can be nested in a directory structure, and when
lint reports an error, it looks up the closest lint.xml file, and
if no configuration is found there, continues searching upwards in
the directory tree. This means that the configuration closest to the
report location takes precedence. Note however, that this has higher
priority than the above all versus id match, so if there is an all
match in a lint.xml
file and an exact match in a more distant
parent lint.xml
file, the closest lint.xml
all match will be
used.
When there are configurations which specify a host, lint will search in this order:
<issue>
configuration which specifies
in="studio"
, then that configuration will be used.
<issue>
configurations do not specify a host,
and these will be consulted next.
Typically lint.xml files are pretty short and simple, but here's one which uses most of the available features. (Note: the HTML version of this isn't properly handling empty elements, so if you're going to copy/paste go to the source file.)
<?xml version="1.0" encoding="UTF-8"?>
<lint lintJars="../checks/local.jar;../checks/custom.jar">
<!-- The special id "all" matches all issues but is only consulted
if there is no specific match -->
<issue id="all" severity="ignore" />
<!-- Possible severities: ignore, information, warning, error, fatal -->
<issue id="ValidActionsXml" severity="error" />
<issue id="ObsoleteLayoutParam">
<!-- The <ignore> tag has two possible attributes: path and regexp (see below) -->
<ignore path="res/layout-xlarge/activation.xml" />
<!-- You can use globbing patterns in the path strings -->
<ignore path="**/layout-x*/onclick.xml" />
<ignore path="res/**/activation.xml" />
</issue>
<issue id="NewApi">
<!-- You can also ignore via a regular expression, this is not only
matched against the path but also the error message -->
<ignore regexp="st.*gs" />
</issue>
<!-- The "in" attribute lets you specify that the element only
applies in a particular tools, such as gradle, studio, etc; this
can be a comma separated list -->
<issue in="studio" id="NewerVersionAvailable" severity="error" />
<!-- You can also use ! to specify that it does not apply in a tool -->
<issue in="!gradle" id="TrulyRandom" severity="error" />
<issue id="UnknownNullness">
<!-- For detectors that support it, you can also specify option values -->
<option name="ignore-deprecated" value="true" />
</issue>
<issue id="TooManyViews">
<option name="maxCount" value="20" />
</issue>
</lint>
Recent Changes
This chapter lists recent changes to lint that affect users of lint. For information about internal improvements and API changes affecting lint check authors, see the API Guide.
8.6
Issue ID | Summary |
---|---|
AccessibilityFocus | Forcing accessibility focus |
AccessibilityScrollActions | Incomplete Scroll Action support |
AccessibilityWindowStateChangedEvent | Use of accessibility window state change events |
CredentialDependency | credentials-play-services-auth is Required |
PictureInPictureIssue | Picture In Picture best practices not followed |
SimilarGradleDependency | Multiple Versions Gradle Dependency |
UnclosedTrace | Incorrect trace section usage |
8.4
Issue ID | Summary |
---|---|
BuildListAdds | Missing add call in buildList |
PublicKeyCredential | Creating public key credential |
SecretInSource | Secret in source code |
LintBaselineFixed | Baseline issues fixed |
LintBaseline
issue was reporting two different types of issues:
Since these are separate problems and you may want to configure one
and not the other to be a warning or an error, the LintBaseline
issue id is now only used for the first type of issue, and the second
one is reported under a new issue ID, LintBaselineFixed
. If you had
previously suppressed LintBaseline
in order to remove both of these
reports, you'l need to also suppress LintBaselineFixed
.
8.3
Issue ID | Summary |
---|---|
ActivityIconColor | Ongoing activity icon is not white |
SelectedPhotoAccess | Behavior change when requesting photo library access |
UseSdkSuppress | Using @SdkSuppress instead of @RequiresApi |
WrongCommentType | Wrong Comment Type |
8.2
Issue ID | Summary |
---|---|
ForegroundServicePermission | Missing permissions required by foregroundServiceType |
ForegroundServiceType | Missing foregroundServiceType attribute in manifest |
IntentWithNullActionLaunch | Unsafe intent launched with no action set |
MutableImplicitPendingIntent | Mutable Implicit PendingIntent is disallowed |
PlaySdkIndexGenericIssues | Library has issues in SDK Index |
StartActivityAndCollapseDeprecated | TileService.startActivityAndCollapse(Intent) is deprecated |
TilePreviewImageFormat | Tile preview is not compliant with standards |
WearBackNavigation | Wear: Disabling Back navigation |
WearMaterialTheme | Using not non-Wear MaterialTheme in a Wear OS project |
WearPasswordInput | Wear: Using password input |
WearRecents | Wear OS: Recents and app resume |
WearSplashScreen | Wear: Use SplashScreen library |
8.1
Issue ID | Summary |
---|---|
NoOp | Finds leftover code constructs which have no side effect or purpose |
UnspecifiedRegisterReceiverFlag | Missing registerReceiver() exported flag |
UnsafeIntentLaunch | Launched unsafe Intent |
UnsafeImplicitIntentLaunch | Implicit intent matches an internal non-exported component |
ReportShortcutUsage | Shortcut usage should be reported |
UseTomlInstead | Mixing and matching Gradle build file and TOML dependencies |
KaptUsageInsteadOfKsp | Using kapt where KSP would also be available |
BomWithoutPlatform | BOM artifact added as a dependency instead of as a platform |
ProviderReadPermissionOnly | Provider with readPermission only and implemented write APIs |
MutableImplicitPendingIntent | Mutable implicit PendingIntent is disallowed |
(The NoOp
and UnsafeImplicitIntentLaunch
lint checks are
currently disabled by default.)
8.0
Issue ID | Summary |
---|---|
ChromeOsOnConfigurationChanged | ChromeOS performance checks in onConfigurationChanged() |
SetAndClearCommunicationDevice | Missing clearCommunicationDevice() after set |
7.4
Issue ID | Summary |
---|---|
PermissionNamingConvention | Custom permissions not following naming convention |
KnownPermissionError | Well-known permission errors, e.g. android:permission="true" |
SystemPermissionTypo | Usage of permissions that look like system permissions, but have typos |
CustomPermissionTypo | Usage of permissions that look like custom permissions from the same project, but have typos |
ReservedSystemPermission | Accidental redefining of a framework permission, or usage of the andriod. prefix |
GestureBackNavigation | Usage of KeyEvent.KEYCODE_BACK |
UnusedTranslation | Unused translation, not declared in localeConfig |
NotificationPermission | Notifications Without android.permission.POST_NOTIFICATIONS |
MonochromeLauncherIcon | Monochrome icon is not defined |
PlaySdkIndexNonCompliant | Library has policy issues in SDK Index |
TileProviderPermissions | TileProvider does not set permission |
SquareAndRoundTilePreviews | TileProvider does not have round and square previews |
InternalInsetResource | Using internal inset dimension resource |
BinderGetCallingInMainThread | Incorrect usage of getCallingUid() or getCallingPid() |
--offline
flag passed to Gradle, and will refrain
from making network calls for checks that normally do (such as
AppLinksAutoVerify
).7.3
Issue ID | Summary |
---|---|
SuspiciousIndentation | Flags suspiciously indented code |
StringFormatTrivial | Avoid trivial conversions in String.format |
WearableActionDuplicate | Duplicate watch face configurations |
EmptySuperCall | Invoking super. on @EmptySuper method |
OpenForTesting | Overriding @OpenForTesting outside tests |
DeprecatedSinceApi | Calling deprecated SDK backport methods |
ReturnThis | Not returning “this” from @ReturnThis methods |
KotlinNullnessAnnotation | Using nullability annotations in Kotlin |
MissingInflatedId | ID not found in inflated resource |
NotificationId0 | Notification Id is 0 |
android.experimental.lint.missingBaselineIsEmptyBaseline=true
in
gradle.properties
, and then run the new task updateLintBaseline
to create or update baselines.7.2
Issue ID | Summary |
---|---|
AssertionSideEffect | Assertions that have side effects |
BidiSpoofing | Misleading bidirectional Unicode strings |
MotionLayoutMissingId | Views inside MotionLayout require an id |
UastImplementation | Avoid UAST implementation classes |
7.1
VisibleForTests
check flagging additional
usages of test-only APIs outside of tests.
Issue ID | Summary |
---|---|
FileEndsWithExt | Flags suspicious usages of File.endsWith(extension) |
DataExtractionRules | Missing data extraction rules |
RedundantLabel | Redundant label on activity in manifest |
DiscouragedApi | Using APIs annotated with @Discouraged |
ViewBindingType | Validation for tools:viewBindingType |
AppBundleLocaleChanges | Handling runtime locale changes |
Issue ID | Summary |
---|---|
MissingTranslation | Now checks for missing translations of plurals |
WrongConstant | Now has quickfixes to replace with constants |
CheckResult | Now also runs in unit tests |
MediaCapabilities
since its advice is no longer the
recommended practice.7.0
Issue ID | Summary |
---|---|
AnnotateVersionCheck | Annotate SDK_INT checks |
CoarseFineLocation | Cannot use ACCESS_FINE_LOCATION without ACCESS_COARSE_LOCATION |
CustomSplashScreen | Application-defined Launch Screen |
CustomX509TrustManager | Implements custom TLS trust manager |
HighSamplingRate | High sensor sampling rate |
IntentFilterExportedReceiver | Unspecified android:exported in manifest |
LaunchActivityFromNotification | Notification Launches Services or BroadcastReceivers |
LeanbackUsesWifi | Using android.hardware.wifi on TV |
MediaCapabilities | Media Capabilities property not specified |
NotificationTrampoline | Notification Trampolines |
NotifyDataSetChanged | Invalidating All RecyclerView Data |
TileProviderPermissions | TileProvider does not set permission |
TrustAllX509TrustManager | Insecure TLS/SSL trust manager |
UnspecifiedImmutableFlag | Missing PendingIntent mutability flag |
WatchFaceEditor | Watch face editor must use launchMode=“standard” |
WebViewClientOnReceivedSslError | Proceeds with the HTTPS connection despite SSL errors |
IntentFilterUniqueDataAttributes | Data tags should only declare unique attributes |
lint
task to the default variant's
lint task instead of running it across all variants and accumulating
results. This is much faster, is usually what you want, and now the
target name will not change based on whether the project has product
flavors, so you can start just running ./gradlew :app:lint
instead
of ./gradlew :app:lintDebug
or :app:lintProDebug
etc.
Furthermore, the lintOptions
block is now just named lint
instead.
4.2
This chapter lists the various environment variables and system properties that Lint will look at. None of these are really intended to be used or guaranteed to be supported in the future, but documenting what they are seems useful.
ANDROID_LINT_INCLUDE_LDPI
Lint's icon checks normally ignore the ldpi
density since it's not
commonly used any more, but you can turn this back on with this
environment variable set to true
.
ANDROID_LINT_MAX_VIEW_COUNT
Lint's TooManyViews
check makes sure that a single layout does not
have more than 80 views. You can set this environment variable to a
different number to change the limit.
ANDROID_LINT_MAX_DEPTH
Lint's TooManyViews
check makes sure that a single layout does not
have a deeper layout hierarchy than 10 levels.You can set this
environment variable to a different number to change the limit.
ANDROID_LINT_NULLNESS_IGNORE_DEPRECATED
Lint's UnknownNullness
which flags any API element which is not
explicitly annotated with nullness annotations, normally skips
deprecated elements. Set this environment variable to true to include
these as well.
Corresponding system property: lint.nullness.ignore-deprecated
.
Note that this setting can also be configured using a proper
lint.xml
setting instead; this is now listed in the documentation
for that check.
ANDROID_SDK_ROOT
Locates the Android SDK root
ANDROID_HOME
Locates the Android SDK root, if $ANDROID_SDK_ROOT
has not been set
JAVA_HOME
Locates the JDK when lint is analyzing JDK (not Android) projects
LINT_XML_ROOT
Normally the search for lint.xml
files proceeds upwards in the
directory hierarchy. In the Gradle integration, the search will stop
at the root Gradle project, but in other build systems, it can
continue up to the root directory. This environment variable sets a
path where the search should stop.
ANDROID_LINT_JARS
A path of jar files (using the path separator — semicolon on Windows, colon elsewhere) for lint to load extra lint checks from
ANDROID_SDK_CACHE_DIR
Sets the directory where lint should read and write its cache files.
Lint has a number of databases that it caches between invocations,
such as its binary representation of the SDK API database, used to
look up API levels quickly. In the Gradle integration of lint, this
cache directory is set to the root build/
directory, but elsewhere
the cache directory is located in a lint
subfolder of the normal
Android tooling cache directory, such as ~/.android
.
LINT_OVERRIDE_CONFIGURATION
Path to a lint XML file which should override any local lint.xml
files closer to reported issues. This provides a way to globally
change configuration.
Corresponding system property: lint.configuration.override
LINT_DO_NOT_REUSE_UAST_ENV
Set to true
to enable a workaround (if affected) for
bug 159733104
until 7.0 is released.
Corresponding system property: lint.do.not.reuse.uast.env
LINT_API_DATABASE
Point lint to an alternative API database XML file instead of the
normally used $SDK/platforms/android-?/data/api-versions.xml
file.
ANDROID_LINT_SKIP_BYTECODE_VERIFIER
If set to true
, lint will not perform bytecode verification of custom
lint check jars from libraries or passed in via command line flags.
Corresponding system property: android.lint.skip.bytecode.verifier
LINT_PRINT_STACKTRACE
If set to true, lint will print the full stack traces of any internal exceptions encountered during analysis. This is useful for authors of lint checks, or for power users who can reproduce a bug and want to report it with more details.
Corresponding system property: lint.print-stacktrace
LINT_TEST_KOTLINC
When writing a lint check unit test, when creating a compiled
or
bytecode
test file, lint can generate the .class file binary
content automatically if it is pointed to the kotlinc
compiler.
LINT_TEST_JAVAC
When writing a lint check unit test, when creating a compiled
or
bytecode
test file, lint can generate the .class file binary
content automatically if it is pointed to the javac
compiler.
LINT_TEST_KOTLINC_NATIVE
When writing a lint check unit test, when creating a klib
file,
lint can generate the .klib
file binary content automatically
if it is pointed to kotlinc-native
.
LINT_TEST_INTEROP
When writing a lint check unit test, when creating a c
or def
test file, lint can generate the .klib
file binary content
automatically if it is pointed to cinterop
.
INCLUDE_EXPENSIVE_LINT_TESTS
When working on lint itself, set this environment variable to true
some really, really expensive tests that we don't want run on the CI
server or by the rest of the development team.
./gradlew lintDebug -Dlint.baselines.continue=true
lint.baselines.continue
When you configure a new baseline, lint normally fails the build after creating the baseline. You can set this system property to true to force lint to continue.
lint.autofix
Turns on auto-fixing (applying safe quickfixes) by default. This is a
shortcut for invoking the lintFix
targets or running the lint
command with --apply-suggestions
.
lint.autofix.imports
If lint.autofix
is on, setting this flag will also include updating
imports and applying reference shortening for updated code. This
is normally only done in the IDE, relying on the safe refactoring
machinery there. Lint's implementation isn't accurate in all cases
(for example, it may apply reference shortening in comments), but
can be enabled when useful (such as large bulk operations along with
manual verification.)
Turns on auto-fixing (applying safe quickfixes) by default. This is a
shortcut for invoking the lintFix
targets or running the lint
command with --apply-suggestions
.
lint.html.prefs
This property allows you to customize lint's HTML reports. It
consists of a comma separated list of property assignments, e.g.
./gradlew :app:lintDebug -Dlint.html.prefs=theme=darcula,window=5
Property | Explanation and Values | Default |
---|---|---|
theme | light , darcula , solarized | light |
window | Number of lines around problem | 3 |
maxIncidents | Maximum incidents shown per issue type | 50 |
splitLimit | Issue count before “More...” button | 8 |
maxPerIssue | Name of split limit prior to 7.0 | 8 |
underlineErrors | If true, wavy underlines, else highlight | true |
lint.unused-resources.exclude-tests
Whether the unused resource check should exclude test sources as referenced resources.
lint.configuration.override
Alias for $LINT_OVERRIDE_CONFIGURATION
lint.print-stacktrace
Alias for $LINT_PRINT_STACKTRACE
lint.do.not.reuse.uast.env
Alias for $LINT_DO_NOT_REUSE_UAST_ENV
android.lint.log-jar-problems
Controls whether lint will complain about custom check lint jar loading problems. By default, true.
android.lint.api-database-binary-path
Point lint to a precomputed per-SDK platform, per-lint binary API database to read from. If the file is not found or uses the wrong format version, lint will fail.
android.lint.skip.bytecode.verifier
Alias for $ANDROID_LINT_SKIP_BYTECODE_VERIFIER
Corresponding system property: android.lint.skip.bytecode.verifier