| <html><head><meta charset="utf-8" lang="kotlin"> |
| |
| </head><body style="visibility: visible;" id="md"><meta charset="UTF-8"><meta http-equiv="content-type" content="text/html;charset=UTF-8"><meta name="viewport" content="width=600, initial-scale=1"><style>body{max-width:680px;margin:auto;padding:20px;text-align:justify;line-height:140%;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-smoothing:antialiased;color:#222;font-family:Palatino,Georgia,"Times New Roman",serif}</style><style>@media print{*{-webkit-print-color-adjust:exact;text-shadow:none !important}}body{counter-reset: h1 paragraph line item list-item}@page{margin:0;size:auto}#mdContextMenu{position:absolute;background:#383838;cursor:default;border:1px solid #999;color:#fff;padding:4px 0px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,"Helvetica Neue",sans-serif;font-size:85%;font-weight:600;border-radius:4px;box-shadow:0px 3px 10px rgba(0,0,0,35%)}#mdContextMenu div{padding:0px 20px}#mdContextMenu div:hover{background:#1659d1}.md code,.md pre{font-family:Menlo,Consolas,monospace;font-size:85%;text-align:left;line-height:140%}.md .mediumToc code,.md longToc code,.md .shortToc code,.md h1 code,.md h2 code,.md h3 code,.md h4 code,.md h5 code,.md h6 code{font-size:unset}.md div.title{font-size:26px;font-weight:800;line-height:120%;text-align:center}.md div.afterTitles{height:10px}.md div.subtitle{text-align:center}.md iframe.textinsert, .md object.textinsert,.md iframe:not(.markdeep){display:block;margin-top:10px;margin-bottom:10px;width:100%;height:75vh;border:1px solid #000;border-radius:4px;background:#f5f5f4}.md .image{display:inline-block}.md img{max-width:100%;page-break-inside:avoid}.md li{text-align:left;text-indent:0}.md pre.listing {width:100%;tab-size:4;-moz-tab-size:4;-o-tab-size:4;counter-reset:line;overflow-x:auto;resize:horizontal}.md pre.listing .linenumbers span.line:before{width:30px;margin-left:-28px;font-size:80%;text-align:right;counter-increment:line;content:counter(line);display:inline-block;padding-right:13px;margin-right:8px;color:#ccc}.md div.tilde{margin:20px 0 -10px;text-align:center}.md .imagecaption,.md .tablecaption,.md .listingcaption{display:inline-block;margin:7px 5px 12px;text-align:justify;font-style:italic}.md img.pixel{image-rendering:-moz-crisp-edges;image-rendering:pixelated}.md blockquote.fancyquote{margin:25px 0 25px;text-align:left;line-height:160%}.md blockquote.fancyquote::before{content:"“";color:#DDD;font-family:Times New Roman;font-size:45px;line-height:0;margin-right:6px;vertical-align:-0.3em}.md span.fancyquote{font-size:118%;color:#777;font-style:italic}.md span.fancyquote::after{content:"”";font-style:normal;color:#DDD;font-family:Times New Roman;font-size:45px;line-height:0;margin-left:6px;vertical-align:-0.3em}.md blockquote.fancyquote .author{width:100%;margin-top:10px;display:inline-block;text-align:right}.md small{font-size:60%}.md big{font-size:150%}.md div.title,contents,.md .tocHeader,.md h1,.md h2,.md h3,.md h4,.md h5,.md h6,.md .shortTOC,.md .mediumTOC,.nonumberh1,.nonumberh2,.nonumberh3,.nonumberh4,.nonumberh5,.nonumberh6{font-family:Verdana,Helvetica,Arial,sans-serif;margin:13.4px 0 13.4px;padding:15px 0 3px;border-top:none;clear:both}.md .tocTop {display:none}.md h1,.md h2,.md h3,.md h4,.md h5,.md h6,.md .nonumberh1,.md .nonumberh2,.md .nonumberh3,.md .nonumberh4,.md .nonumberh5,.md .nonumberh6{page-break-after:avoid;break-after:avoid}.md svg.diagram{display:block;font-family:Menlo,Consolas,monospace;font-size:85%;text-align:center;stroke-linecap:round;stroke-width:2px;page-break-inside:avoid;stroke:#000;fill:#000}.md svg.diagram .opendot{fill:#fff}.md svg.diagram .shadeddot{fill:#CCC}.md svg.diagram .dotteddot{stroke:#000;stroke-dasharray:4;fill:none}.md svg.diagram text{stroke:none}@media print{@page{margin:1in 5mm;transform: scale(150%)}}@media print{.md .pagebreak{page-break-after:always;visibility:hidden}}.md a{font-family:Georgia,Palatino,'Times New Roman'}.md h1,.md .tocHeader,.md .nonumberh1{border-bottom:3px solid;font-size:20px;font-weight:bold;}.md h1,.md .nonumberh1{counter-reset:h2 h3 h4 h5 h6}.md h2,.md .nonumberh2{counter-reset:h3 h4 h5 h6;border-bottom:2px solid #999;color:#555;font-weight:bold;font-size:18px;}.md h3,.md h4,.md h5,.md h6,.md .nonumberh3,.md .nonumberh4,.md .nonumberh5,.md .nonumberh6{font-family:Verdana,Helvetica,Arial,sans-serif;color:#555;font-size:16px;}.md h3{counter-reset:h4 h5 h6}.md h4{counter-reset:h5 h6}.md h5{counter-reset:h6}.md div.table{margin:16px 0 16px 0}.md table{border-collapse:collapse;line-height:140%;page-break-inside:avoid}.md table.table{margin:auto}.md table.calendar{width:100%;margin:auto;font-size:11px;font-family:Verdana,Helvetica,Arial,sans-serif}.md table.calendar th{font-size:16px}.md .today{background:#ECF8FA}.md .calendar .parenthesized{color:#999;font-style:italic}.md table.table th{color:#FFF;background-color:#AAA;border:1px solid #888;padding:8px 15px 8px 15px}.md table.table td{padding:5px 15px 5px 15px;border:1px solid #888}.md table.table tr:nth-child(even){background:#EEE}.md pre.tilde{border-top: 1px solid #CCC;border-bottom: 1px solid #CCC;padding: 5px 0 5px 20px;margin:0 0 0 0;background:#FCFCFC;page-break-inside:avoid}.md a.target{width:0px;height:0px;visibility:hidden;font-size:0px;display:inline-block}.md a:link, .md a:visited{color:#38A;text-decoration:none}.md a:link:hover{text-decoration:underline}.md dt{font-weight:700}.md dl>dd{margin-top:-8px; margin-bottom:8px}.md dl>table{margin:35px 0 30px}.md code{page-break-inside:avoid;} @media print{.md .listing code{white-space:pre-wrap}}.md .endnote{font-size:13px;line-height:15px;padding-left:10px;text-indent:-10px}.md .bib{padding-left:80px;text-indent:-80px;text-align:left}.markdeepFooter{font-size:9px;text-align:right;padding-top:80px;color:#999}.md .mediumTOC{float:right;font-size:12px;line-height:15px;border-left:1px solid #CCC;padding-left:15px;margin:15px 0px 15px 25px}.md .mediumTOC .level1{font-weight:600}.md .longTOC .level1{font-weight:600;display:block;padding-top:12px;margin:0 0 -20px}.md .shortTOC{text-align:center;font-weight:bold;margin-top:15px;font-size:14px}.md .admonition{position:relative;margin:1em 0;padding:.4rem 1rem;border-radius:.2rem;border-left:2.5rem solid rgba(68,138,255,.4);background-color:rgba(68,138,255,.15);}.md .admonition-title{font-weight:bold;border-bottom:solid 1px rgba(68,138,255,.4);padding-bottom:4px;margin-bottom:4px;margin-left: -1rem;padding-left:1rem;margin-right:-1rem;border-color:rgba(68,138,255,.4)}.md .admonition.tip{border-left:2.5rem solid rgba(50,255,90,.4);background-color:rgba(50,255,90,.15)}.md .admonition.tip::before{content:"\24d8";font-weight:bold;font-size:150%;position:relative;top:3px;color:rgba(26,128,46,.8);left:-2.95rem;display:block;width:0;height:0}.md .admonition.tip>.admonition-title{border-color:rgba(50,255,90,.4)}.md .admonition.warn,.md .admonition.warning{border-left:2.5rem solid rgba(255,145,0,.4);background-color:rgba(255,145,0,.15)}.md .admonition.warn::before,.md .admonition.warning::before{content:"\26A0";font-weight:bold;font-size:150%;position:relative;top:2px;color:rgba(128,73,0,.8);left:-2.95rem;display:block;width:0;height:0}.md .admonition.warn>.admonition-title,.md .admonition.warning>.admonition-title{border-color:rgba(255,145,0,.4)}.md .admonition.error{border-left: 2.5rem solid rgba(255,23,68,.4);background-color:rgba(255,23,68,.15)}.md .admonition.error>.admonition-title{border-color:rgba(255,23,68,.4)}.md .admonition.error::before{content: "\2612";font-family:"Arial";font-size:200%;position:relative;color:rgba(128,12,34,.8);top:-2px;left:-3rem;display:block;width:0;height:0}.md .admonition p:last-child{margin-bottom:0}.md li.checked,.md li.unchecked{list-style:none;overflow:visible;text-indent:-1.2em}.md li.checked:before,.md li.unchecked:before{content:"\2611";display:block;float:left;width:1em;font-size:120%}.md li.unchecked:before{content:"\2610"}</style><style>.md h1::before { |
| content:counter(h1) " "; |
| counter-increment: h1;margin-right:10px} |
| |
| .md h2::before { |
| content:counter(h1) "."counter(h2) " "; |
| counter-increment: h2;margin-right:10px} |
| |
| .md h3::before { |
| content:counter(h1) "."counter(h2) "."counter(h3) " "; |
| counter-increment: h3;margin-right:10px} |
| |
| .md h4::before { |
| content:counter(h1) "."counter(h2) "."counter(h3) "."counter(h4) " "; |
| counter-increment: h4;margin-right:10px} |
| |
| .md h5::before { |
| content:counter(h1) "."counter(h2) "."counter(h3) "."counter(h4) "."counter(h5) " "; |
| counter-increment: h5;margin-right:10px} |
| |
| .md h6::before { |
| content:counter(h1) "."counter(h2) "."counter(h3) "."counter(h4) "."counter(h5) "."counter(h6) " "; |
| counter-increment: h6;margin-right:10px} |
| |
| </style><style>.hljs{display:block;overflow-x:auto;padding:0.5em;background:#fff;color:#000;-webkit-text-size-adjust:none}.hljs-comment{color:#006a00}.hljs-keyword{color:#02E}.hljs-literal,.nginx .hljs-title{color:#aa0d91}.method,.hljs-list .hljs-title,.hljs-tag .hljs-title,.setting .hljs-value,.hljs-winutils,.tex .hljs-command,.http .hljs-title,.hljs-request,.hljs-status,.hljs-name{color:#008}.hljs-envvar,.tex .hljs-special{color:#660}.hljs-string{color:#c41a16}.hljs-tag .hljs-value,.hljs-cdata,.hljs-filter .hljs-argument,.hljs-attr_selector,.apache .hljs-cbracket,.hljs-date,.hljs-regexp{color:#080}.hljs-sub .hljs-identifier,.hljs-pi,.hljs-tag,.hljs-tag .hljs-keyword,.hljs-decorator,.ini .hljs-title,.hljs-shebang,.hljs-prompt,.hljs-hexcolor,.hljs-rule .hljs-value,.hljs-symbol,.hljs-symbol .hljs-string,.hljs-number,.css .hljs-function,.hljs-function .hljs-title,.coffeescript .hljs-attribute{color:#A0C}.hljs-function .hljs-title{font-weight:bold;color:#000}.hljs-class .hljs-title,.smalltalk .hljs-class,.hljs-type,.hljs-typename,.hljs-tag .hljs-attribute,.hljs-doctype,.hljs-class .hljs-id,.hljs-built_in,.setting,.hljs-params,.clojure .hljs-attribute{color:#5c2699}.hljs-variable{color:#3f6e74}.css .hljs-tag,.hljs-rule .hljs-property,.hljs-pseudo,.hljs-subst{color:#000}.css .hljs-class,.css .hljs-id{color:#9b703f}.hljs-value .hljs-important{color:#ff7700;font-weight:bold}.hljs-rule .hljs-keyword{color:#c5af75}.hljs-annotation,.apache .hljs-sqbracket,.nginx .hljs-built_in{color:#9b859d}.hljs-preprocessor,.hljs-preprocessor *,.hljs-pragma{color:#643820}.tex .hljs-formula{background-color:#eee;font-style:italic}.diff .hljs-header,.hljs-chunk{color:#808080;font-weight:bold}.diff .hljs-change{background-color:#bccff9}.hljs-addition{background-color:#baeeba}.hljs-deletion{background-color:#ffc8bd}.hljs-comment .hljs-doctag{font-weight:bold}.method .hljs-id{color:#000}</style><style>div.title { padding-top: 40px; } div.afterTitles { height: 15px; }</style><meta charset="utf-8" lang="kotlin"> |
| |
| <span class="md"><p><title>Android User Guide</title></p><div class="title"> Android User Guide </div> |
| |
| <div class="afterTitles"></div><div class="mediumTOC"><center><b>Contents</b></center><p><a href="#" class="tocTop">(Top)</a><br> |
| <a href="#baselines" class="level1"><span class="tocNumber">1 </span>Baselines</a><br> |
| <a href="#creatingabaseline" class="level1"><span class="tocNumber">2 </span>Creating a Baseline</a><br> |
| <a href="#creatingabaseline/customizethebaseline" class="level2"><span class="tocNumber">2.1 </span>Customize the baseline</a><br> |
| <a href="#creatingabaseline/baselinewarning" class="level2"><span class="tocNumber">2.2 </span>Baseline warning</a><br> |
| <a href="#performancetuning" class="level1"><span class="tocNumber">3 </span>Performance Tuning</a><br> |
| <a href="#performancetuning/use7.0andincrementallint" class="level2"><span class="tocNumber">3.1 </span>Use 7.0 and Incremental Lint</a><br> |
| <a href="#performancetuning/usethelintdebugtarget,notlint" class="level2"><span class="tocNumber">3.2 </span>Use the <code>lintDebug</code> target, not <code>lint</code></a><br> |
| <a href="#performancetuning/onlyanalyzeapp/leafmodules" class="level2"><span class="tocNumber">3.3 </span>Only analyze app/leaf modules</a><br> |
| <a href="#performancetuning/don'tanalyzetestsources" class="level2"><span class="tocNumber">3.4 </span>Don't analyze test sources</a><br> |
| <a href="#performancetuning/don'tusecheckallwarnings" class="level2"><span class="tocNumber">3.5 </span>Don't use checkAllWarnings</a><br> |
| <a href="#performancetuning/uselatestversion" class="level2"><span class="tocNumber">3.6 </span>Use latest version</a><br> |
| <a href="#performancetuning/givelintalotofram" class="level2"><span class="tocNumber">3.7 </span>Give lint a lot of RAM</a><br> |
| <a href="#performancetuning/findingslowlintchecks" class="level2"><span class="tocNumber">3.8 </span>Finding Slow Lint Checks</a><br> |
| <a href="#suppressinglintchecks" class="level1"><span class="tocNumber">4 </span>Suppressing Lint Checks</a><br> |
| <a href="#configuringusinglint.xmlfiles" class="level1"><span class="tocNumber">5 </span>Configuring Using lint.xml Files</a><br> |
| <a href="#configuringusinglint.xmlfiles/xmlsyntax" class="level2"><span class="tocNumber">5.1 </span>XML Syntax</a><br> |
| <a href="#configuringusinglint.xmlfiles/nesting&precedence" class="level2"><span class="tocNumber">5.2 </span>Nesting & Precedence</a><br> |
| <a href="#configuringusinglint.xmlfiles/samplelint.xmlfile" class="level2"><span class="tocNumber">5.3 </span>Sample lint.xml file</a><br> |
| <a href="#appendix:recentchanges" class="level1"><span class="tocNumber">6 </span>Appendix: Recent Changes</a><br> |
| <a href="#appendix:environmentvariablesandsystemproperties" class="level1"><span class="tocNumber">7 </span>Appendix: Environment Variables and System Properties</a><br> |
| <a href="#appendix:environmentvariablesandsystemproperties/environmentvariables" class="level2"><span class="tocNumber">7.1 </span>Environment Variables</a><br> |
| <a href="#appendix:environmentvariablesandsystemproperties/environmentvariables/detectorconfigurationvariables" class="level3"><span class="tocNumber">7.1.1 </span>Detector Configuration Variables</a><br> |
| <a href="#appendix:environmentvariablesandsystemproperties/environmentvariables/lintconfigurationvariables" class="level3"><span class="tocNumber">7.1.2 </span>Lint Configuration Variables</a><br> |
| <a href="#appendix:environmentvariablesandsystemproperties/environmentvariables/lintdevelopmentvariables" class="level3"><span class="tocNumber">7.1.3 </span>Lint Development Variables</a><br> |
| <a href="#appendix:environmentvariablesandsystemproperties/systemproperties" class="level2"><span class="tocNumber">7.2 </span>System Properties</a><br> |
| </p></div> |
| |
| <p></p><p> |
| |
| This chapter inlines all the usage information into a single |
| long book, suitable for printing or reading on a tablet. |
| |
| </p><p> |
| |
| <strong class="asterisk">Recent Changes</strong> |
| |
| </p><p> |
| |
| 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. |
| |
| </p><p> |
| |
| <strong class="asterisk">7.0</strong> |
| |
| </p><p> |
| |
| </p><ul> |
| <li class="asterisk">New built-in lint checks:</li></ul> |
| |
| <p></p><p> |
| |
| </p><div class="table"><table class="table"><tbody><tr><th style="text-align:left"> Issue ID </th><th style="text-align:left"> Summary </th></tr> |
| <tr><td style="text-align:left"> <code>AnnotateVersionCheck</code> </td><td style="text-align:left"> Annotate SDK_INT checks </td></tr> |
| <tr><td style="text-align:left"> <code>CoarseFineLocation</code> </td><td style="text-align:left"> Cannot use <code>ACCESS_FINE_LOCATION</code> without <code>ACCESS_COARSE_LOCATION</code> </td></tr> |
| <tr><td style="text-align:left"> <code>CustomSplashScreen</code> </td><td style="text-align:left"> Application-defined Launch Screen </td></tr> |
| <tr><td style="text-align:left"> <code>CustomX509TrustManager</code> </td><td style="text-align:left"> Implements custom TLS trust manager </td></tr> |
| <tr><td style="text-align:left"> <code>HighSamplingRate</code> </td><td style="text-align:left"> High sensor sampling rate </td></tr> |
| <tr><td style="text-align:left"> <code>IntentFilterExportedReceiver</code> </td><td style="text-align:left"> Unspecified <code>android:exported</code> in manifest </td></tr> |
| <tr><td style="text-align:left"> <code>LaunchActivityFromNotification</code> </td><td style="text-align:left"> Notification Launches Services or BroadcastReceivers </td></tr> |
| <tr><td style="text-align:left"> <code>LeanbackUsesWifi</code> </td><td style="text-align:left"> Using android.hardware.wifi on TV </td></tr> |
| <tr><td style="text-align:left"> <code>MediaCapabilities</code> </td><td style="text-align:left"> Media Capabilities property not specified </td></tr> |
| <tr><td style="text-align:left"> <code>NotificationTrampoline</code> </td><td style="text-align:left"> Notification Trampolines </td></tr> |
| <tr><td style="text-align:left"> <code>NotifyDataSetChanged</code> </td><td style="text-align:left"> Invalidating All RecyclerView Data </td></tr> |
| <tr><td style="text-align:left"> <code>TileProviderPermissions</code> </td><td style="text-align:left"> TileProvider does not set permission </td></tr> |
| <tr><td style="text-align:left"> <code>TrustAllX509TrustManager</code> </td><td style="text-align:left"> Insecure TLS/SSL trust manager </td></tr> |
| <tr><td style="text-align:left"> <code>UnspecifiedImmutableFlag</code> </td><td style="text-align:left"> Missing <code>PendingIntent</code> mutability flag </td></tr> |
| <tr><td style="text-align:left"> <code>WatchFaceEditor</code> </td><td style="text-align:left"> Watch face editor must use launchMode=“standard” </td></tr> |
| </tbody></table></div> |
| |
| <p></p><p> |
| |
| </p><ul> |
| <li class="asterisk">Lint checks now include information for reported incidents where the |
| lint check came from, such as which library artifact provided it. |
| This should make it easier to request enhancements or file bugs |
| around false positives or false negatives. |
| |
| <p></p><p> |
| |
| </p></li> |
| <li class="asterisk">Lint “partial analysis” mode is now integrated in lint. It is |
| enabled by default, but you can disable it by modifying |
| <code>gradle.properties</code> to include |
| |
| <p></p><p> |
| |
| <code>android.enableParallelLint=false</code> |
| |
| </p><p> |
| |
| </p></li> |
| <li class="asterisk">The API check now also looks up operator overloading functions.</li></ul> |
| |
| <p></p><p> |
| |
| <strong class="asterisk">4.2</strong> |
| |
| </p><p> |
| |
| </p><ul> |
| <li class="asterisk">Improved support for lint.xml configuration files. You can now |
| specify lint.xml files in project source folders, where the settings |
| will apply recursively within just that folder. You can also specify |
| options for detectors, and enable or disable checks for specific |
| clients (such as just in Gradle, or just in the IDE, and so on.) |
| |
| <p></p><p> |
| |
| </p></li> |
| <li class="asterisk">Support for SARIF reports; a static analysis report file format |
| supported by for example GitHub, allowing the results to be |
| visualized in a unified way on CI servers.</li></ul> |
| |
| <p></p> |
| <a class="target" name="baselines"> </a><a class="target" name="baselines"> </a><a class="target" name="toc1"> </a><h1>Baselines</h1> |
| |
| <a class="target" name="creatingabaseline"> </a><a class="target" name="creatingabaseline"> </a><a class="target" name="toc2"> </a><h1>Creating a Baseline</h1> |
| <p> |
| |
| |
| 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. |
| |
| </p><p> |
| |
| To create a baseline snapshot, modify your project's <code>build.gradle</code>`` |
| file as follows. |
| |
| </p><pre class="listing tilde"><code><span class="line">android {</span> |
| <span class="line"> lintOptions {</span> |
| <span class="line"> baseline file(<span class="hljs-string">"lint-baseline.xml"</span>)</span> |
| <span class="line"> }</span> |
| <span class="line">}</span></code></pre><p> |
| |
| When you first add this line, the <code>lint-baseline.xml</code> 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. |
| |
| </p><p> |
| |
| Then, run lint from the IDE (<strong class="asterisk">Analyze > Inspect Code</strong>) 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. |
| |
| </p><pre class="listing backtick"><code><span class="line"> $ ./gradlew lintDebug</span> |
| <span class="line"> ...</span> |
| <span class="line"> Wrote XML report to file:///app/lint-baseline.xml</span> |
| <span class="line"> Created baseline file /app/lint-baseline.xml</span></code></pre><p> |
| |
| Running lint records all of the current issues in the |
| <code>lint-baseline.xml</code> 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. |
| |
| </p> |
| <a class="target" name="customizethebaseline"> </a><a class="target" name="creatingabaseline/customizethebaseline"> </a><a class="target" name="toc2.1"> </a><h2>Customize the baseline</h2> |
| <p> |
| |
| |
| 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. |
| |
| </p><pre class="listing tilde"><code><span class="line">android {</span> |
| <span class="line"> lintOptions {</span> |
| <span class="line"> check <span class="hljs-string">'NewApi'</span>, <span class="hljs-string">'HandlerLeak'</span></span> |
| <span class="line"> baseline file(<span class="hljs-string">"lint-baseline.xml"</span>)</span> |
| <span class="line"> }</span> |
| <span class="line">}</span></code></pre><p> |
| |
| After you create the baseline, if you add any new warnings to the |
| codebase, lint lists only the newly introduced bugs. |
| |
| </p> |
| <a class="target" name="baselinewarning"> </a><a class="target" name="creatingabaseline/baselinewarning"> </a><a class="target" name="toc2.2"> </a><h2>Baseline warning</h2> |
| <p> |
| |
| |
| 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. |
| |
| </p><p> |
| |
| 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. |
| |
| </p><p> |
| |
| </p><div class="admonition note"><div class="admonition-title"> Baselines are enabled when you run inspections in batch</div> |
| |
| <p></p><p> |
| |
| mode in the IDE, but they are ignored for the in-editor checks that |
| run in the background when you are editing a file. The reason is that |
| baselines are intended for the case where a codebase has a massive |
| number of existing warnings, but you do want to fix issues locally |
| while you touch the code.</p></div> |
| |
| <p></p><p> |
| |
| <a href="https://developer.android.com/studio/write/lint#snapshot">Official documentation</a> |
| |
| </p> |
| <a class="target" name="performancetuning"> </a><a class="target" name="performancetuning"> </a><a class="target" name="toc3"> </a><h1>Performance Tuning</h1> |
| <p> |
| |
| |
| 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. |
| |
| </p><p> |
| |
| This chapter provides some tips on how to improve the performance of |
| lint on CI servers. |
| |
| </p><p> |
| |
| </p><div class="admonition tip">Some of these suggestions are not true in all cases, so you might |
| want to time before and after to verify that for your project each |
| change is an improvement.</div> |
| |
| <p></p> |
| <a class="target" name="use7.0andincrementallint"> </a><a class="target" name="performancetuning/use7.0andincrementallint"> </a><a class="target" name="toc3.1"> </a><h2>Use 7.0 and Incremental Lint</h2> |
| <p> |
| |
| |
| 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. |
| |
| </p><p> |
| |
| To use this: |
| |
| </p><p> |
| |
| </p><ol start="1"> |
| <li class="number">Update to the latest 7.0 canary 12 or later. |
| |
| <p></p><p> |
| |
| </p></li> |
| <li class="number">Update your CI configuration such that it does not clean the working |
| directories between each build.</li></ol> |
| |
| <p></p><p> |
| |
| 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. |
| |
| </p> |
| <a class="target" name="usethelintdebugtarget,notlint"> </a><a class="target" name="performancetuning/usethelintdebugtarget,notlint"> </a><a class="target" name="toc3.2"> </a><h2>Use the <code>lintDebug</code> target, not <code>lint</code></h2> |
| <p> |
| |
| |
| If you run “./gradlew tasks” you'll see that there's a <code>lint</code> 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: |
| |
| </p><p> |
| |
| </p><ul> |
| <li class="asterisk"><code>lint</code> |
| </li> |
| <li class="asterisk"><code>lintDebug</code> |
| </li> |
| <li class="asterisk"><code>lintRelease</code></li></ul> |
| |
| <p></p><p> |
| |
| If you have defined additional build types or product flavors, you can |
| end up with many more of these — <code>lintFreeDebug</code>, <code>lintProDebug</code>, |
| <code>lintFreeBeta</code>, <code>lintProBeta</code>, etc. |
| |
| </p><p> |
| |
| <strong class="asterisk">Don't configure your CI job to run the <code>lint</code> task; pick a specific |
| variant instead, such as <code>lintDebug</code></strong>. The reason this is so |
| important, is that what the <code>lint</code> task really does is run lint over |
| and over again, for <em class="asterisk">each</em> 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). |
| |
| </p><p> |
| |
| 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 |
| <code>src/debug/res/values</code>), 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 <code>lintRelease</code> and you're not going |
| to miss much. |
| |
| </p><p> |
| |
| </p><div class="admonition note">You're probably shipping your release variant, not your debug |
| variant, so instead of running <code>lintDebug</code> it's probably more |
| accurate to run <code>lintRelease</code>. However, unless you're doing anything |
| variant specific, it's unlikely that this matters, and running |
| <code>lintRelease</code> can take significantly longer since it performs more |
| build time optimizations.</div> |
| |
| <p></p><p> |
| |
| If you have lots of variants this makes a huge difference; with 7 |
| variants, <code>lint</code> will take ~7x longer than <code>lintDebug</code> !! (modulo some |
| minor caching) |
| |
| </p><p> |
| |
| </p><div class="admonition tip">In 7.0 and Arctic Fox we're changing the behavior of the <code>lint</code> |
| target such that it is just an alias for <code>lintDebug</code>, so once you |
| update to 7.0 this is no longer a problem.</div> |
| |
| <p></p> |
| <a class="target" name="onlyanalyzeapp/leafmodules"> </a><a class="target" name="performancetuning/onlyanalyzeapp/leafmodules"> </a><a class="target" name="toc3.3"> </a><h2>Only analyze app/leaf modules</h2> |
| <p> |
| |
| |
| 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 |
| |
| </p><p> |
| |
| </p><ol start="1"> |
| <li class="number">Turn on checkDependencies mode, and |
| |
| <p></p><p> |
| |
| </p></li> |
| <li class="number">Only run lint on the app modules, instead of recursively running |
| lint on each module.</li></ol> |
| |
| <p></p><p> |
| |
| To do this, first add this to your app module's build.gradle file: |
| |
| </p><pre class="listing backtick"><code><span class="line"><span class="hljs-string">android</span> {</span> |
| <span class="line"> <span class="hljs-string">...</span></span> |
| <span class="line"> <span class="hljs-string">lintOptions</span> {</span> |
| <span class="line"> <span class="hljs-string">...</span></span> |
| <span class="line"> <span class="hljs-string">checkDependencies</span> <span class="hljs-literal">true</span></span> |
| <span class="line"> <span class="hljs-string">...</span></span> |
| <span class="line"> }</span> |
| <span class="line">}</span></code></pre><p> |
| |
| Then instead of running <code>./gradlew lintDebug</code>, run <code>./gradlew |
| :app:lintDebug</code>. |
| |
| </p><p> |
| |
| 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). |
| |
| </p><p> |
| |
| </p><div class="admonition note">Note that <code>checkDependencies true</code> will also cause lint to analyze |
| Kotlin-only or Java-only modules, which the normal <code>./gradlew |
| lintDebug</code> 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 |
| <code>checkDependencies true</code>. However, for this scenario it's probably a |
| change you want to make anyway.</div> |
| |
| <p></p><p> |
| |
| 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 <code>./gradlew lintDebug</code>. 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. |
| |
| </p><p> |
| |
| </p><div class="admonition note">This mode used to be on by default, since it has better usability. |
| We had to turn it off for performance reasons, because many users |
| were running redundant targets. But in 7.0 we've added a new |
| mechanism (partial analysis) which solves these performance |
| problems, so we will most likely turn this mode back on by default.</div> |
| |
| <p></p> |
| <a class="target" name="don'tanalyzetestsources"> </a><a class="target" name="performancetuning/don'tanalyzetestsources"> </a><a class="target" name="toc3.4"> </a><h2>Don't analyze test sources</h2> |
| <p> |
| |
| |
| Lint has two flags controlling what to do about test sources: |
| <code>checkTestSources</code> and <code>ignoreTestSources</code>. These mean different things. |
| |
| </p><p> |
| |
| The <code>checkTestSources</code> 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 <code>ignoreTestSources</code> 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? |
| |
| </p><p> |
| |
| Add the following to your app module's <code>build.gradle</code> 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: |
| |
| </p><pre class="listing backtick"><code><span class="line"><span class="hljs-string">android</span> {</span> |
| <span class="line"> <span class="hljs-string">...</span></span> |
| <span class="line"> <span class="hljs-string">lintOptions</span> {</span> |
| <span class="line"> <span class="hljs-string">...</span></span> |
| <span class="line"> <span class="hljs-string">ignoreTestSources</span> <span class="hljs-literal">true</span></span> |
| <span class="line"> <span class="hljs-string">...</span></span> |
| <span class="line"> }</span> |
| <span class="line">}</span></code></pre> |
| <a class="target" name="don'tusecheckallwarnings"> </a><a class="target" name="performancetuning/don'tusecheckallwarnings"> </a><a class="target" name="toc3.5"> </a><h2>Don't use checkAllWarnings</h2> |
| <p> |
| |
| |
| Lint has a <code>checkAllWarnings</code> 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 (<em class="asterisk">“because I want all the |
| tips I can get”</em> is what I heard from one developer). |
| |
| </p><p> |
| |
| 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 |
| <code>WrongThreadInterprocedural</code> check, which is particularly expensive, |
| though in recent versions we've specifically exempted this check from |
| <code>checkAllWarnings</code>.) |
| |
| </p> |
| <a class="target" name="uselatestversion"> </a><a class="target" name="performancetuning/uselatestversion"> </a><a class="target" name="toc3.6"> </a><h2>Use latest version</h2> |
| <p> |
| |
| |
| 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.) |
| |
| </p> |
| <a class="target" name="givelintalotofram"> </a><a class="target" name="performancetuning/givelintalotofram"> </a><a class="target" name="toc3.7"> </a><h2>Give lint a lot of RAM</h2> |
| <p> |
| |
| |
| 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. |
| |
| </p><p> |
| |
| This is <em class="asterisk">especially</em> 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. |
| |
| </p><p> |
| |
| One user reported this result: |
| </p><blockquote> |
| I have a very large project (with over 2000 classes) and giving lint |
| more memory had a huge effect: |
| |
| <p></p><p> |
| |
| <code>./gradlew -Dorg.gradle.jvmargs=-Xmx2g app:lintDebug</code> takes 25m 18s |
| |
| </p><p> |
| |
| <code>./gradlew -Dorg.gradle.jvmargs=-Xmx8g app:lintDebug</code> takes 8m 57s!</p></blockquote> |
| |
| <p></p> |
| <a class="target" name="findingslowlintchecks"> </a><a class="target" name="performancetuning/findingslowlintchecks"> </a><a class="target" name="toc3.8"> </a><h2>Finding Slow Lint Checks</h2> |
| <p> |
| |
| |
| 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: |
| |
| </p><pre class="listing backtick"><code><span class="line"><span class="hljs-string">$</span> <span class="hljs-string">./gradlew</span> <span class="hljs-string">lintDebug</span> <span class="hljs-string">-no-daemon</span> <span class="hljs-string">-Dorg.gradle.jvmargs="..."</span></span> |
| <span class="line"></span> |
| <span class="line"><span class="hljs-string">BUILD</span> <span class="hljs-string">SUCCESSFUL</span> <span class="hljs-string">in</span> <span class="hljs-string">10s</span></span> |
| <span class="line"><span class="hljs-attr">15 actionable tasks:</span> <span class="hljs-number">1</span> <span class="hljs-string">executed,</span> <span class="hljs-number">14</span> <span class="hljs-string">up-to-date</span></span> |
| <span class="line"></span> |
| <span class="line"><span class="hljs-attr">Lint detector performance stats:</span></span> |
| <span class="line"> <span class="hljs-string">total</span> <span class="hljs-string">self</span> <span class="hljs-string">calls</span></span> |
| <span class="line"> <span class="hljs-string">LintDriver</span> <span class="hljs-number">3709 </span><span class="hljs-string">ms</span> <span class="hljs-number">1302 </span><span class="hljs-string">ms</span> <span class="hljs-number">2821</span></span> |
| <span class="line"><span class="hljs-string">TopDownAnalyzerFacadeForJVM</span> <span class="hljs-number">2121 </span><span class="hljs-string">ms</span> <span class="hljs-number">2121 </span><span class="hljs-string">ms</span> <span class="hljs-number">6</span></span> |
| <span class="line"> <span class="hljs-string">IconDetector</span> <span class="hljs-number">81</span> <span class="hljs-string">ms</span> <span class="hljs-number">81</span> <span class="hljs-string">ms</span> <span class="hljs-number">257</span></span> |
| <span class="line"> <span class="hljs-string">OverdrawDetector</span> <span class="hljs-number">51</span> <span class="hljs-string">ms</span> <span class="hljs-number">51</span> <span class="hljs-string">ms</span> <span class="hljs-number">36</span></span> |
| <span class="line"> <span class="hljs-string">InvalidPackageDetector</span> <span class="hljs-number">34</span> <span class="hljs-string">ms</span> <span class="hljs-number">34</span> <span class="hljs-string">ms</span> <span class="hljs-number">51744</span></span> |
| <span class="line"> <span class="hljs-string">GradleDetector</span> <span class="hljs-number">20</span> <span class="hljs-string">ms</span> <span class="hljs-number">20</span> <span class="hljs-string">ms</span> <span class="hljs-number">94</span></span> |
| <span class="line"> <span class="hljs-string">LocaleFolderDetector</span> <span class="hljs-number">11</span> <span class="hljs-string">ms</span> <span class="hljs-number">11</span> <span class="hljs-string">ms</span> <span class="hljs-number">986</span></span> |
| <span class="line"> <span class="hljs-string">RestrictToDetector</span> <span class="hljs-number">11</span> <span class="hljs-string">ms</span> <span class="hljs-number">11</span> <span class="hljs-string">ms</span> <span class="hljs-number">19</span></span> |
| <span class="line"> <span class="hljs-string">ApiDetector</span> <span class="hljs-number">11</span> <span class="hljs-string">ms</span> <span class="hljs-number">11</span> <span class="hljs-string">ms</span> <span class="hljs-number">1255</span></span> |
| <span class="line"> <span class="hljs-string">PrivateResourceDetector</span> <span class="hljs-number">10</span> <span class="hljs-string">ms</span> <span class="hljs-number">10</span> <span class="hljs-string">ms</span> <span class="hljs-number">422</span></span> |
| <span class="line"> [<span class="hljs-string">...</span>]</span></code></pre><p> |
| Here you can see that <code>InvalidPackageDetector</code> 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. |
| |
| </p><p> |
| |
| You can read more about this tool in <a href="https://groups.google.com/g/lint-dev/c/mwpTCaQPXYU/m/YKc4EcMYAgAJ">this |
| post</a>. |
| |
| </p><p> |
| |
| 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! |
| |
| </p><p> |
| |
| </p><div class="admonition warning">One thing to be aware of is that the “blame” is not entirely fair. |
| There are a number of expensive operations in lint, and especially |
| symbol resolution, which is cached. That means that the first |
| unlucky detector that comes along has to perform the computation, |
| and subsequent detectors just get to reuse the result. Because of |
| this, it's not always the case that a particular detector is a |
| performance culprit, and as soon as you disable it, a new detector |
| moves to the top of the list paying the same initialization costs. |
| The main use for this tool is to find extreme or unusual performance |
| behaviors.</div> |
| |
| <p></p> |
| <a class="target" name="suppressinglintchecks"> </a><a class="target" name="suppressinglintchecks"> </a><a class="target" name="toc4"> </a><h1>Suppressing Lint Checks</h1> |
| <p> |
| |
| |
| Lint errors can be suppressed in a variety of ways: |
| |
| </p><p> |
| |
| </p><ol start="1"> |
| <li class="number">With a <code>@SuppressLint</code> annotation in the Java code |
| </li> |
| <li class="number">With a <code>tools:ignore</code> attribute in the XML file |
| </li> |
| <li class="number">With a //noinspection comment in the source code |
| </li> |
| <li class="number">With ignore flags specified in the <code>build.gradle</code> file, |
| as explained below |
| </li> |
| <li class="number">With a <code>lint.xml</code> configuration file in the project |
| </li> |
| <li class="number">With a <code>lint.xml</code> configuration file passed to lint |
| via the —config flag |
| </li> |
| <li class="number">With the —ignoreflag passed to lint |
| </li> |
| <li class="number">With a <a href="#baselines">baseline</a></li></ol> |
| |
| <p></p><p> |
| |
| To suppress a lint warning with an annotation, add |
| a <code>@SuppressLint("id")</code> 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 <code>"UnusedResources"</code> or <code>{"UnusedResources", |
| "UnusedIds"}</code>, or it can be <code>"all"</code> to suppress all lint |
| warnings in the given scope. |
| |
| </p><p> |
| |
| You can also use <code>@Suppress</code> in Kotlin or <code>@SuppressWarnings</code> |
| in Java. |
| |
| </p><p> |
| |
| To suppress a lint warning with a comment, add |
| a <code>//noinspection id</code> comment on the line before the statement |
| with the error. |
| |
| </p><p> |
| |
| To suppress a lint warning in an XML file, add a |
| <code>tools:ignore="id"</code> 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 <code>xmlns:android</code> |
| declaration: |
| <code>xmlns:tools="http://schemas.android.com/tools"</code> |
| |
| </p><p> |
| |
| To suppress a lint warning in a <code>build.gradle</code> file, add a |
| section like this: |
| |
| </p><pre class="listing backtick"><code><span class="line">android {</span> |
| <span class="line"> lintOptions {</span> |
| <span class="line"> disable 'TypographyFractions','TypographyQuotes'</span> |
| <span class="line"> }</span> |
| <span class="line">}</span></code></pre><p> |
| |
| Here we specify a comma separated list of issue id's after the |
| disable command. You can also use <code>warning</code> or <code>error</code> instead |
| of <code>disable</code> to change the severity of issues. |
| |
| </p><p> |
| |
| To suppress lint warnings with a configuration XML file, |
| create a file named <code>lint.xml</code>. See the |
| <a href="#configuringusinglintxmlfiles">lint.xml configuration</a> document |
| for more details. |
| |
| </p><p> |
| |
| To suppress lint checks from the command line, pass the |
| <code>--ignore</code> flag with a comma separated list of ids to be suppressed, such as: |
| |
| </p><pre class="listing backtick"><code><span class="line"><span class="hljs-meta">$</span><span class="bash"> lint --ignore UnusedResources,UselessLeaf /my/project/path</span></span></code></pre><p> |
| |
| For more information, see |
| <a href="https://developer.android.com/studio/write/lint.html#config" class="url">https://developer.android.com/studio/write/lint.html#config</a> |
| |
| </p> |
| <a class="target" name="configuringusinglint.xmlfiles"> </a><a class="target" name="configuringusinglint.xmlfiles"> </a><a class="target" name="toc5"> </a><h1>Configuring Using lint.xml Files</h1> |
| <p> |
| |
| |
| In addition to configuring lint with command line flags or Gradle DSL |
| options, you can also create XML files named <code>lint.xml</code>, which lint |
| will look for automatically. |
| |
| </p><p> |
| |
| Like <code>.gitignore</code> files, these can be nested, so you can for example |
| create a <code>lint.xml</code> file which sets the severity of an issue to error, |
| but then in a specific subfolder change the severity to be just a |
| warning. |
| |
| </p><p> |
| |
| This chapter describes the syntax of <code>lint.xml</code> files. |
| |
| </p> |
| <a class="target" name="xmlsyntax"> </a><a class="target" name="configuringusinglint.xmlfiles/xmlsyntax"> </a><a class="target" name="toc5.1"> </a><h2>XML Syntax</h2> |
| <p> |
| |
| |
| The root tag is always <code><lint></code>, and it can contain one or more |
| <code><issue></code> elements. Each <issue> can specify the following |
| attributes: <code>id</code>: 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”. |
| |
| </issue></p><p> |
| |
| <code>in</code>: 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 <code>in="!studio"</code>. |
| |
| </p><p> |
| |
| In addition, the <issue> element can specify one or more children: |
| |
| </issue></p><p> |
| |
| <code><ignore path="..."></code>: Specifies a path to ignore. Can contain the |
| globbing character “*” to match any substring in the path. <code><ignore regexp="..."></code>: Specifies either a regular expression to ignore. The |
| regular expression is matched against both the location of the error |
| and the error message itself. <code><option name="..." value="..."></code>: |
| Specifies an option value. This can be used to configure some lint |
| checks with options. |
| |
| </p><p> |
| |
| Finally, on the root <lint> element you can specify a number of |
| attributes, such as <code>lintJars</code> (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.) |
| |
| </lint></p> |
| <a class="target" name="nesting&precedence"> </a><a class="target" name="configuringusinglint.xmlfiles/nesting&precedence"> </a><a class="target" name="toc5.2"> </a><h2>Nesting & Precedence</h2> |
| <p> |
| |
| |
| You can specify configurations for “all”, but these will be |
| matched after an exact match has been done. E.g. if we have |
| both <code><issue id="all" severity="ignore"></code> and <code><issue id="MyId" severity="error"></code>, the severity for <code>MyId</code> will be “error”“ since |
| that's a more exact match. |
| |
| </p><p> |
| |
| 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 <code>all</code> |
| match in a <code>lint.xml</code> file and an exact match in a more distant |
| parent <code>lint.xml</code> file, the closest <code>lint.xml</code> all match will be |
| used. |
| |
| </p><p> |
| |
| When there are configurations which specify a host, lint will search |
| in this order: |
| |
| </p><p> |
| |
| </p><ol start="1"> |
| <li class="number">An exact host match. E.g. if you're running in Studio and there is |
| an <code><issue></code> configuration which specifies |
| <code>in="studio"</code>, then that configuration will be used. |
| </li> |
| <li class="number">A match which does not specify a host. Usually <code><issue></code> |
| configurations do not specify a host, |
| and these will be consulted next. |
| </li> |
| <li class="number">A match which specifies other hosts. For example, if you're |
| running in Studio and a configuration specifies |
| ”!gradle“, this will match after the other attempts.</li></ol> |
| |
| <p></p> |
| <a class="target" name="samplelint.xmlfile"> </a><a class="target" name="configuringusinglint.xmlfiles/samplelint.xmlfile"> </a><a class="target" name="toc5.3"> </a><h2>Sample lint.xml file</h2> |
| <p> |
| |
| |
| 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.) |
| |
| </p><pre class="listing tilde"><code><span class="line"><span class="hljs-comment"><!--?xml version="1.0" encoding="UTF-8"?--></span></span> |
| <span class="line"><span class="hljs-tag"><<span class="hljs-name">lint</span> <span class="hljs-attr">lintjars</span>=<span class="hljs-string">"../checks/local.jar;../checks/custom.jar"</span>></span></span> |
| <span class="line"> <span class="hljs-comment"><!-- The special id "all" matches all issues but is only consulted</span> |
| <span class="line"> if there is no specific match --></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">issue</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"all"</span> <span class="hljs-attr">severity</span>=<span class="hljs-string">"ignore"</span>></span></span> |
| <span class="line"> <span class="hljs-comment"><!-- Possible severities: ignore, information, warning, error, fatal --></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">issue</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"ValidActionsXml"</span> <span class="hljs-attr">severity</span>=<span class="hljs-string">"error"</span>></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">issue</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"ObsoleteLayoutParam"</span>></span></span> |
| <span class="line"> <span class="hljs-comment"><!-- The <ignore> tag has two possible attributes: path and regexp (see below) --></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">ignore</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"res/layout-xlarge/activation.xml"</span>></span></span> |
| <span class="line"> <span class="hljs-comment"><!-- You can use globbing patterns in the path strings --></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">ignore</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"**/layout-x*/onclick.xml"</span>></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">ignore</span> <span class="hljs-attr">path</span>=<span class="hljs-string">"res/**/activation.xml"</span>></span></span> |
| <span class="line"> <span class="hljs-tag"></<span class="hljs-name">ignore</span>></span><span class="hljs-tag"></<span class="hljs-name">ignore</span>></span><span class="hljs-tag"></<span class="hljs-name">ignore</span>></span><span class="hljs-tag"></<span class="hljs-name">issue</span>></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">issue</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"NewApi"</span>></span></span> |
| <span class="line"> <span class="hljs-comment"><!-- You can also ignore via a regular expression, this is not only</span> |
| <span class="line"> matched against the path but also the error message --></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">ignore</span> <span class="hljs-attr">regexp</span>=<span class="hljs-string">"st.*gs"</span>></span></span> |
| <span class="line"> <span class="hljs-tag"></<span class="hljs-name">ignore</span>></span><span class="hljs-tag"></<span class="hljs-name">issue</span>></span></span> |
| <span class="line"> <span class="hljs-comment"><!-- The "in" attribute lets you specify that the element only</span> |
| <span class="line"> applies in a particular tools, such as gradle, studio, etc; this</span> |
| <span class="line"> can be a comma separated list --></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">issue</span> <span class="hljs-attr">in</span>=<span class="hljs-string">"studio"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"NewerVersionAvailable"</span> <span class="hljs-attr">severity</span>=<span class="hljs-string">"error"</span>></span></span> |
| <span class="line"> <span class="hljs-comment"><!-- You can also use ! to specify that it does not apply in a tool --></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">issue</span> <span class="hljs-attr">in</span>=<span class="hljs-string">"!gradle"</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"TrulyRandom"</span> <span class="hljs-attr">severity</span>=<span class="hljs-string">"error"</span>></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">issue</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"UnknownNullness"</span>></span></span> |
| <span class="line"> <span class="hljs-comment"><!-- For detectors that support it, you can also specify option values --></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">option</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"ignore-deprecated"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"true"</span>></span></span> |
| <span class="line"> <span class="hljs-tag"></<span class="hljs-name">option</span>></span><span class="hljs-tag"></<span class="hljs-name">issue</span>></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">issue</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"TooManyViews"</span>></span></span> |
| <span class="line"> <span class="hljs-tag"><<span class="hljs-name">option</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"maxCount"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"20"</span>></span></span> |
| <span class="line"> <span class="hljs-tag"></<span class="hljs-name">option</span>></span><span class="hljs-tag"></<span class="hljs-name">issue</span>></span></span> |
| <span class="line"><span class="hljs-tag"></<span class="hljs-name">issue</span>></span><span class="hljs-tag"></<span class="hljs-name">issue</span>></span><span class="hljs-tag"></<span class="hljs-name">issue</span>></span><span class="hljs-tag"></<span class="hljs-name">issue</span>></span><span class="hljs-tag"></<span class="hljs-name">lint</span>></span></span></code></pre><p> |
| |
| |
| |
| </p> |
| <a class="target" name="appendix:recentchanges"> </a><a class="target" name="appendix:recentchanges"> </a><a class="target" name="toc6"> </a><h1>Appendix: Recent Changes</h1> |
| <p> |
| |
| |
| <strong class="asterisk">Recent Changes</strong> |
| |
| </p><p> |
| |
| 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. |
| |
| </p><p> |
| |
| <strong class="asterisk">7.0</strong> |
| |
| </p><p> |
| |
| </p><ul> |
| <li class="asterisk">New built-in lint checks:</li></ul> |
| |
| <p></p><p> |
| |
| </p><div class="table"><table class="table"><tbody><tr><th style="text-align:left"> Issue ID </th><th style="text-align:left"> Summary </th></tr> |
| <tr><td style="text-align:left"> <code>AnnotateVersionCheck</code> </td><td style="text-align:left"> Annotate SDK_INT checks </td></tr> |
| <tr><td style="text-align:left"> <code>CoarseFineLocation</code> </td><td style="text-align:left"> Cannot use <code>ACCESS_FINE_LOCATION</code> without <code>ACCESS_COARSE_LOCATION</code> </td></tr> |
| <tr><td style="text-align:left"> <code>CustomSplashScreen</code> </td><td style="text-align:left"> Application-defined Launch Screen </td></tr> |
| <tr><td style="text-align:left"> <code>CustomX509TrustManager</code> </td><td style="text-align:left"> Implements custom TLS trust manager </td></tr> |
| <tr><td style="text-align:left"> <code>HighSamplingRate</code> </td><td style="text-align:left"> High sensor sampling rate </td></tr> |
| <tr><td style="text-align:left"> <code>IntentFilterExportedReceiver</code> </td><td style="text-align:left"> Unspecified <code>android:exported</code> in manifest </td></tr> |
| <tr><td style="text-align:left"> <code>LaunchActivityFromNotification</code> </td><td style="text-align:left"> Notification Launches Services or BroadcastReceivers </td></tr> |
| <tr><td style="text-align:left"> <code>LeanbackUsesWifi</code> </td><td style="text-align:left"> Using android.hardware.wifi on TV </td></tr> |
| <tr><td style="text-align:left"> <code>MediaCapabilities</code> </td><td style="text-align:left"> Media Capabilities property not specified </td></tr> |
| <tr><td style="text-align:left"> <code>NotificationTrampoline</code> </td><td style="text-align:left"> Notification Trampolines </td></tr> |
| <tr><td style="text-align:left"> <code>NotifyDataSetChanged</code> </td><td style="text-align:left"> Invalidating All RecyclerView Data </td></tr> |
| <tr><td style="text-align:left"> <code>TileProviderPermissions</code> </td><td style="text-align:left"> TileProvider does not set permission </td></tr> |
| <tr><td style="text-align:left"> <code>TrustAllX509TrustManager</code> </td><td style="text-align:left"> Insecure TLS/SSL trust manager </td></tr> |
| <tr><td style="text-align:left"> <code>UnspecifiedImmutableFlag</code> </td><td style="text-align:left"> Missing <code>PendingIntent</code> mutability flag </td></tr> |
| <tr><td style="text-align:left"> <code>WatchFaceEditor</code> </td><td style="text-align:left"> Watch face editor must use launchMode=“standard” </td></tr> |
| </tbody></table></div> |
| |
| <p></p><p> |
| |
| </p><ul> |
| <li class="asterisk">Lint checks now include information for reported incidents where the |
| lint check came from, such as which library artifact provided it. |
| This should make it easier to request enhancements or file bugs |
| around false positives or false negatives. |
| |
| <p></p><p> |
| |
| </p></li> |
| <li class="asterisk">Lint “partial analysis” mode is now integrated in lint. It is |
| enabled by default, but you can disable it by modifying |
| <code>gradle.properties</code> to include |
| |
| <p></p><p> |
| |
| <code>android.enableParallelLint=false</code> |
| |
| </p><p> |
| |
| </p></li> |
| <li class="asterisk">The API check now also looks up operator overloading functions.</li></ul> |
| |
| <p></p><p> |
| |
| <strong class="asterisk">4.2</strong> |
| |
| </p><p> |
| |
| </p><ul> |
| <li class="asterisk">Improved support for lint.xml configuration files. You can now |
| specify lint.xml files in project source folders, where the settings |
| will apply recursively within just that folder. You can also specify |
| options for detectors, and enable or disable checks for specific |
| clients (such as just in Gradle, or just in the IDE, and so on.) |
| |
| <p></p><p> |
| |
| </p></li> |
| <li class="asterisk">Support for SARIF reports; a static analysis report file format |
| supported by for example GitHub, allowing the results to be |
| visualized in a unified way on CI servers.</li></ul> |
| |
| <p></p> |
| <a class="target" name="appendix:environmentvariablesandsystemproperties"> </a><a class="target" name="appendix:environmentvariablesandsystemproperties"> </a><a class="target" name="toc7"> </a><h1>Appendix: Environment Variables and System Properties</h1> |
| <p> |
| |
| |
| 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. |
| |
| </p> |
| <a class="target" name="environmentvariables"> </a><a class="target" name="appendix:environmentvariablesandsystemproperties/environmentvariables"> </a><a class="target" name="toc7.1"> </a><h2>Environment Variables</h2> |
| |
| <a class="target" name="detectorconfigurationvariables"> </a><a class="target" name="appendix:environmentvariablesandsystemproperties/environmentvariables/detectorconfigurationvariables"> </a><a class="target" name="toc7.1.1"> </a><h3>Detector Configuration Variables</h3> |
| <p> |
| |
| |
| </p><dl><dt><code>ANDROID_LINT_INCLUDE_LDPI</code></dt><dd><p> Lint's icon checks normally ignore the <code>ldpi</code> density since it's not |
| commonly used any more, but you can turn this back on with this |
| environment variable set to <code>true</code>. |
| |
| </p></dd><dt><code>ANDROID_LINT_MAX_VIEW_COUNT</code></dt><dd><p> Lint's <code>TooManyViews</code> 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. |
| |
| </p></dd><dt><code>ANDROID_LINT_MAX_DEPTH</code></dt><dd><p> Lint's <code>TooManyViews</code> 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. |
| |
| </p></dd><dt><code>ANDROID_LINT_NULLNESS_IGNORE_DEPRECATED</code></dt><dd><p> Lint's <code>UnknownNullness</code> 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. |
| |
| </p><p> |
| |
| Corresponding system property: <code>lint.nullness.ignore-deprecated</code> |
| |
| </p></dd></dl><p></p> |
| <a class="target" name="lintconfigurationvariables"> </a><a class="target" name="appendix:environmentvariablesandsystemproperties/environmentvariables/lintconfigurationvariables"> </a><a class="target" name="toc7.1.2"> </a><h3>Lint Configuration Variables</h3> |
| <p> |
| |
| |
| </p><dl><dt><code>ANDROID_SDK_ROOT</code></dt><dd><p> Locates the Android SDK root |
| |
| </p></dd><dt><code>ANDROID_HOME</code></dt><dd><p> Locates the Android SDK root, if <code>$ANDROID_SDK_ROOT</code> has not been set |
| |
| </p></dd><dt><code>JAVA_HOME</code></dt><dd><p> Locates the JDK when lint is analyzing JDK (not Android) projects |
| |
| </p></dd><dt><code>LINT_XML_ROOT</code></dt><dd><p> Normally the search for <code>lint.xml</code> 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. |
| |
| </p></dd><dt><code>ANDROID_LINT_JARS</code></dt><dd><p> A path of jar files (using the path separator — semicolon on |
| Windows, colon elsewhere) for lint to load extra lint checks from |
| |
| </p></dd><dt><code>ANDROID_SDK_CACHE_DIR</code></dt><dd><p> 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 <code>build/</code> directory, but elsewhere |
| the cache directory is located in a <code>lint</code> subfolder of the normal |
| Android tooling cache directory, such as <code>~/.android</code>. |
| |
| </p></dd><dt><code>LINT_OVERRIDE_CONFIGURATION</code></dt><dd><p> Path to a lint XML file which should override any local <code>lint.xml</code> |
| files closer to reported issues. This provides a way to globally |
| change configuration. |
| |
| </p><p> |
| |
| Corresponding system property: <code>lint.configuration.override</code> |
| |
| </p></dd><dt><code>LINT_DO_NOT_REUSE_UAST_ENV</code></dt><dd><p> Set to <code>true</code> to enable a workaround (if affected) for |
| <a href="https://issuetracker.google.com/159733104">bug 159733104</a> |
| until 7.0 is released. |
| |
| </p><p> |
| |
| Corresponding system property: <code>lint.do.not.reuse.uast.env</code> |
| |
| </p></dd><dt><code>LINT_API_DATABASE</code></dt><dd><p> Point lint to an alternative API database XML file instead of the |
| normally used <code>$SDK/platforms/android-?/data/api-versions.xml</code> file. |
| |
| </p></dd></dl><p></p> |
| <a class="target" name="lintdevelopmentvariables"> </a><a class="target" name="appendix:environmentvariablesandsystemproperties/environmentvariables/lintdevelopmentvariables"> </a><a class="target" name="toc7.1.3"> </a><h3>Lint Development Variables</h3> |
| <p> |
| |
| |
| </p><dl><dt><code>LINT_PRINT_STACKTRACE</code></dt><dd><p> 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. |
| |
| </p><p> |
| |
| Corresponding system property: <code>lint.print-stacktrace</code> |
| |
| </p></dd><dt><code>LINT_TEST_KOTLINC</code></dt><dd><p> When writing a lint check unit test, when creating a <code>compiled</code> or |
| <code>bytecode</code> test file, lint can generate the .class file binary |
| content automatically if it is pointed to the <code>kotlinc</code> compiler. |
| |
| </p></dd><dt><code>LINT_TEST_JAVAC</code></dt><dd><p> When writing a lint check unit test, when creating a <code>compiled</code> or |
| <code>bytecode</code> test file, lint can generate the .class file binary |
| content automatically if it is pointed to the <code>javac</code> compiler. |
| |
| </p></dd><dt><code>INCLUDE_EXPENSIVE_LINT_TESTS</code></dt><dd><p> When working on lint itself, set this environment variable to <code>true</code> |
| some really, really expensive tests that we don't want run on the CI |
| server or by the rest of the development team. |
| |
| </p></dd></dl><p></p> |
| <a class="target" name="systemproperties"> </a><a class="target" name="appendix:environmentvariablesandsystemproperties/systemproperties"> </a><a class="target" name="toc7.2"> </a><h2>System Properties</h2> |
| <p> |
| |
| |
| |
| |
| </p><div class="admonition tip">To set system properties when running lint via Gradle, try for |
| example <code>./gradlew lintDebug -Dlint.baselines.continue=true</code></div> |
| |
| <p></p><p> |
| |
| </p><dl><dt><code>lint.baselines.continue</code></dt><dd><p> 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. |
| |
| </p></dd><dt><code>lint.autofix</code></dt><dd><p> Turns on auto-fixing (applying safe quickfixes) by default. This is a |
| shortcut for invoking the <code>lintFix</code> targets or running the <code>lint</code> |
| command with <code>--apply-suggestions</code>. |
| |
| </p></dd><dt><code>lint.html.prefs</code></dt><dd><p> This property allows you to customize lint's HTML reports. It |
| consists of a comma separated list of property assignments, e.g. |
| <code>./gradlew :app:lintDebug -Dlint.html.prefs=theme=darcula,window=5</code> |
| |
| </p></dd></dl><div class="table"><table class="table"><tbody><tr><th style="text-align:left"> Property </th><th style="text-align:left"> Explanation and Values </th><th style="text-align:left"> Default </th></tr> |
| <tr><td style="text-align:left"> <code>theme</code> </td><td style="text-align:left"> <code>light</code>, <code>darcula</code>, <code>solarized</code> </td><td style="text-align:left"> <code>light</code> </td></tr> |
| <tr><td style="text-align:left"> <code>window</code> </td><td style="text-align:left"> Number of lines around problem </td><td style="text-align:left"> 3 </td></tr> |
| <tr><td style="text-align:left"> <code>maxIncidents</code> </td><td style="text-align:left"> Maximum incidents shown per issue type </td><td style="text-align:left"> 50 </td></tr> |
| <tr><td style="text-align:left"> <code>splitLimit</code> </td><td style="text-align:left"> Issue count before “More...” button </td><td style="text-align:left"> 8 </td></tr> |
| <tr><td style="text-align:left"> <code>maxPerIssue</code> </td><td style="text-align:left"> Name of split limit prior to 7.0 </td><td style="text-align:left"> 8 </td></tr> |
| <tr><td style="text-align:left"> <code>underlineErrors</code> </td><td style="text-align:left"> If true, wavy underlines, else highlight </td><td style="text-align:left"> <code>true</code> </td></tr> |
| </tbody></table></div> |
| |
| <p></p><p> |
| |
| </p><dl><table><tbody><tr valign="top"><td><dt><code>lint.unused-resources.exclude-tests</code></dt></td><td><dd><p> Whether the unused resource check should exclude test sources as |
| referenced resources. |
| |
| </p></dd></td></tr><tr valign="top"><td><dt><code>lint.configuration.override</code></dt></td><td><dd><p> Alias for <code>$LINT_OVERRIDE_CONFIGURATION</code> |
| |
| </p></dd></td></tr><tr valign="top"><td><dt><code>lint.print-stacktrace</code></dt></td><td><dd><p> Alias for <code>$LINT_PRINT_STACKTRACE</code> |
| |
| </p></dd></td></tr><tr valign="top"><td><dt><code>lint.do.not.reuse.uast.env</code></dt></td><td><dd><p> Alias for <code>$LINT_DO_NOT_REUSE_UAST_ENV</code> |
| |
| </p></dd></td></tr><tr valign="top"><td><dt><code>android.lint.log-jar-problems</code></dt></td><td><dd><p> Controls whether lint will complain about custom check lint jar |
| loading problems. By default, true. |
| |
| </p></dd></td></tr></tbody></table></dl><script>window.alreadyProcessedMarkdeep||(document.body.style.visibility=“visible”)</script> |
| <p></p></span><div id="mdContextMenu" style="visibility:hidden"></div><div class="markdeepFooter"><i>formatted by <a href="https://casual-effects.com/markdeep" style="color:#999">Markdeep 1.13 </a></i><div style="display:inline-block;font-size:13px;font-family:'Times New Roman',serif;vertical-align:middle;transform:translate(-3px,-1px)rotate(135deg);">✒</div></div></body></html> |