<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/">
	<channel>
		<title>What Is Android Lint and How It Helps Write Maintainable Code | Infinum</title>
		<atom:link href="https://infinum.com/blog/what-is-android-lint-and-how-helps-write-maintainable-code/feed/" rel="self" type="application/rss+xml" />
		<link>https://infinum.com/blog/what-is-android-lint-and-how-helps-write-maintainable-code/</link>
		<description>Building digital products</description>
		<lastBuildDate>Tue, 14 Apr 2026 07:52:12 +0000</lastBuildDate>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>

					<item>
				<image>
					<url>7956https://infinum.com/uploads/2019/04/what-is-android-lint-and-how-helps-write-maintainable-code-0.webp</url>
				</image>
				<title>What Is Android Lint and How It Helps Write Maintainable Code</title>
				<link>https://infinum.com/blog/what-is-android-lint-and-how-helps-write-maintainable-code/</link>
				<pubDate>Thu, 04 Apr 2019 13:00:00 +0000</pubDate>
				<dc:creator>Sven Vidak</dc:creator>
				<guid isPermaLink="false">https://infinum.com/the-capsized-eight/what-is-android-lint-and-how-helps-write-maintainable-code/</guid>
				<description>
					<![CDATA[<p>Classic developer oversights: using an API added in the newer version, actions requiring specific permissions, missing translations, etc.</p>
<p>The post <a href="https://infinum.com/blog/what-is-android-lint-and-how-helps-write-maintainable-code/">What Is Android Lint and How It Helps Write Maintainable Code</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</description>
				<content:encoded>
					<![CDATA[<div
	class="wrapper"
	data-id="es-202"
	 data-animation-target='inner-items'>
		
			<div class="wrapper__inner">
			<div class="block-blog-content js-block-blog-content">
	
<div class="block-blog-content-sidebar" data-id="es-92">
	</div>

<div class="block-blog-content-main">
	
<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-95"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-93">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-94'
	>
	When developers are not careful enough, things can go south. Classic developer oversights include the usage of an API added in the newer version that is not supported in the old versions, actions that require specific permissions, missing translations, just to name a few.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-98"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-96">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-97'
	>
	On top of that, Java, Kotlin, as well as any other programming languages have their own set of programming constructs that might result in poor performance.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-101"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-99">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-100'
	>
	Hello, Lint</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-104"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-102">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-103'
	>
	We use a tool called Lint (or Linter) to prevent such issues. Lint is a tool for static code analysis that helps developers catch potential issues before the code even compiles. It runs multiple checks on the source code that can detect issues like unused variables or function arguments, condition simplification, wrong scopes, undefined variables or functions, poorly optimized code, etc. When we talk about Android development, there are <a href="https://android.googlesource.com/platform/tools/base/+/master/lint/libs/lint-checks/src/main/java/com/android/tools/lint/checks">hundreds of existing Lint checks</a> available out-of-the-box.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-107"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-105">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-106'
	>
	But sometimes, we need to detect specific issues in our codebase that are not covered by those existing checks.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-110"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-108">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-109'
	>
	Hello, custom Lint check</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-113"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-111">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-112'
	>
	Before we start coding, let’s define our goal and see how to implement each part of that goal in terms of a Lint API. The goal is to create a check to detect the wrong method call on an object. The idea of this check is to detect if the method for setting click listener on an Android View component is the one that will throttle multiple consecutive clicks so we can avoid opening the same activity, or calling an API multiple times.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-116"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-114">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-115'
	>
	Custom Lint checks are written as a part of the standard Java (or Kotlin) module. The easiest way to start is to create a simple Gradle-based project (it doesn’t have to be an Android project).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-119"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-117">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-118'
	>
	Next, you’d want to add Lint dependencies. In your module’s <code>build.gradle</code> file add:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-121"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-groovy github-light" data-language="groovy" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">compileOnly </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">com.android.tools.lint:lint-api:</span><span class="token" style="color: #24292e;">$l</span><span class="token" style="color: #24292e;">i</span><span class="token" style="color: #24292e;">n</span><span class="token" style="color: #24292e;">t</span><span class="token" style="color: #24292e;">V</span><span class="token" style="color: #24292e;">e</span><span class="token" style="color: #24292e;">r</span><span class="token" style="color: #24292e;">s</span><span class="token" style="color: #24292e;">i</span><span class="token" style="color: #24292e;">o</span><span class="token" style="color: #24292e;">n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">compileOnly </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">com.android.tools.lint:lint-checks:</span><span class="token" style="color: #24292e;">$l</span><span class="token" style="color: #24292e;">i</span><span class="token" style="color: #24292e;">n</span><span class="token" style="color: #24292e;">t</span><span class="token" style="color: #24292e;">V</span><span class="token" style="color: #24292e;">e</span><span class="token" style="color: #24292e;">r</span><span class="token" style="color: #24292e;">s</span><span class="token" style="color: #24292e;">i</span><span class="token" style="color: #24292e;">o</span><span class="token" style="color: #24292e;">n</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-124"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-122">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-123'
	>
	Now, there’s a trick I’ve learned by researching this topic. <code>lintVersion</code> should be <code>gradlePluginVersion + 23.0.0</code>. <code>gradlePluginVersion</code> is a variable defined in root <code>build.gradle</code> project when you create an Android project using Android Studio and at this moment, the latest stable version is 3.3.0. That means that <code>lintVersion</code> should be 26.3.0.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-127"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-125">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-126'
	>
	Each Lint check consists of 4 parts:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-130"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-128">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-129'
	>
	<li><strong>Issue</strong> – the problem in our code we are trying to prevent from happening. When Lint check fails, this is what is reported to the user</li><li><strong>Detector</strong> – a tool for finding a problem that exposes parts of the source code to us in terms of a Lint API classes</li><li><strong>Implementation</strong> – scope in which a problem might happen (source file, XML file, compiled code, …)</li><li><strong>Registry</strong> – custom Lint check registry, which will be used alongside the existing registry that contains predefined checks</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-133"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-131">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-132'
	>
	Implementation</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-136"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-134">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-135'
	>
	Let’s start by creating an implementation for our custom check. Each implementation consists of a class that implements a detector and a scope.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-138"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">val </span><span class="token">correctClickListenerImplementation </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">Implementation</span><span class="token">(CorrectClickListenerDetector</span><span class="token">::</span><span class="token" style="color: #6f42c1;">class</span><span class="token">.java, Scope.JAVA_FILE_SCOPE)
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-141"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-139">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-140'
	>
	Have in mind that <code>Scope.JAVA_FILE_SCOPE</code> will also work for Kotlin classes.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-144"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-142">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-143'
	>
	Issue</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-147"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-145">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-146'
	>
	The next step is to use this implementation for defining an issue. Each issue consists of several parts:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-150"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-148">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-149'
	>
	<li><strong>ID</strong> – unique identifier</li><li><strong>Description</strong> – short (5-6 words) summary of an issue</li><li><strong>Explanation</strong> – full issue explanation with a suggestion on how to fix it</li><li><strong>Category</strong> – category of an issue (performance, translation, security, etc.)</li><li>Priority – the importance of the issue, in a range from 1 to 10 with 10 being the highest. This will be used to sort issues in a report generated by running Lint task</li><li>Severity – a severity of an issue (fatal, error, warning, info, or ignore)</li><li><strong>Implementation</strong> – implementation that will be used to detect this issue</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-152"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">val </span><span class="token">ISSUE_CLICK_LISTENER </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Issue</span><span class="token">.create</span><span class="token">(
</span></span><span class="line"><span class="token">    id </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">UnsafeClickListener</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">,
</span></span><span class="line"><span class="token">    briefDescription </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Unsafe click listener</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">, 
</span></span><span class="line"><span class="token">    explanation </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;&quot;&quot;</span><span class="token" style="color: #032f62;">&quot;
</span></span><span class="line"><span class="token" style="color: #032f62;">        This check ensures you call click listener that is throttled 
</span></span><span class="line"><span class="token" style="color: #032f62;">        instead of a normal one which does not prevent double clicks.
</span></span><span class="line"><span class="token" style="color: #032f62;">        </span><span class="token" style="color: #032f62;">&quot;&quot;&quot;</span><span class="token">.trimIndent</span><span class="token">(),
</span></span><span class="line"><span class="token">    category </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Category.CORRECTNESS,
</span></span><span class="line"><span class="token">    priority </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">6</span><span class="token">,
</span></span><span class="line"><span class="token">    severity </span><span class="token" style="color: #d73a49;">=</span><span class="token"> Severity.WARNING,
</span></span><span class="line"><span class="token">    implementation </span><span class="token" style="color: #d73a49;">=</span><span class="token"> correctClickListenerImplementation
</span></span><span class="line"><span class="token">)
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-155"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-153">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-154'
	>
	Detector</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-158"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-156">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-157'
	>
	Lint API offers interfaces for each scope you can define in the implementation. Each of these interfaces exposes methods that you can override and access parts of the code you are interested in.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-161"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="lists" data-id="es-159">
	<ul	class='typography typography--size-16-text-roman js-typography lists__typography'
	data-id='es-160'
	>
	<li><strong>UastScanner</strong> – Java or Kotlin files (UAST – <a href="https://www.techopedia.com/definition/22431/abstract-syntax-tree-ast">Unified Abstract Syntax Tree</a>)</li><li><strong>ClassScanner</strong> – compiled files (bytecode)</li><li><strong>BinaryResourceScanner</strong> – binary resources like bitmaps or <code>res/raw</code> files</li><li><strong>ResourceFolderScanner</strong> – resources folders (not specific files in them)</li><li><strong>XmlScanner</strong> – XML files</li><li><strong>GradleScanner</strong> – Gradle files</li><li><strong>OtherFileScanner</strong> – everything else</li></ul></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-164"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-162">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-163'
	>
	Also, <code>Detector</code> class is a base class that has dummy implementations of all the methods each of the above interfaces exposes so you are not forced to implement a complete interface in case you need only one method.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-167"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-165">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-166'
	>
	Now, we are ready to implement a detector that will check the correct method call on an object.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-169"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token" style="color: #d73a49;">const</span><span class="token"> </span><span class="token">val </span><span class="token">REPORT_MESSAGE </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Use setThrottlingClickListener</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">/**</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #6a737d;"> * Custom detector class that extends base Detector class and specific
</span></span><span class="line"><span class="token" style="color: #6a737d;"> * interface depending on which part of the code we want to analyze.
</span></span><span class="line"><span class="token" style="color: #6a737d;"> </span><span class="token" style="color: #6a737d;">*/</span><span class="token">
</span></span><span class="line"><span class="token">class CorrectClickListenerDetector </span><span class="token">: </span><span class="token" style="color: #6f42c1;">Detector</span><span class="token">(), Detector</span><span class="token">.UastScanner </span><span class="token">{
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">/**</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #6a737d;">* Method that defines which elements of the code we want to analyze.
</span></span><span class="line"><span class="token" style="color: #6a737d;">* There are many similar methods for different elements in the code,
</span></span><span class="line"><span class="token" style="color: #6a737d;">* but for our use-case, we want to analyze method calls so we return
</span></span><span class="line"><span class="token" style="color: #6a737d;">* just one element representing method calls.
</span></span><span class="line"><span class="token" style="color: #6a737d;">*/</span><span class="token">
</span></span><span class="line"><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun getApplicableUastTypes</span><span class="token">()</span><span class="token">: </span><span class="token" style="color: #6f42c1;">List</span><span class="token">&lt;</span><span class="token" style="color: #6f42c1;">Class</span><span class="token">&lt;</span><span class="token" style="color: #6f42c1;">out</span><span class="token"> </span><span class="token" style="color: #6f42c1;">UElement</span><span class="token">&gt;&gt;? </span><span class="token">{
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token">listOf</span><span class="token">&lt;</span><span class="token" style="color: #6f42c1;">Class</span><span class="token">&lt;</span><span class="token" style="color: #6f42c1;">out</span><span class="token"> </span><span class="token" style="color: #6f42c1;">UElement</span><span class="token">&gt;&gt;</span><span class="token">(UCallExpression</span><span class="token">::</span><span class="token" style="color: #6f42c1;">class</span><span class="token">.java)
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token" style="color: #6a737d;">/**</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #6a737d;">    * Since we&amp;#8217;ve defined applicable UAST types, we have to override the
</span></span><span class="line"><span class="token" style="color: #6a737d;">    * method that will create UAST handler for those types.
</span></span><span class="line"><span class="token" style="color: #6a737d;">    * Handler requires implementation of an UElementHandler which is a
</span></span><span class="line"><span class="token" style="color: #6a737d;">    * class that defines a number of different methods that handle
</span></span><span class="line"><span class="token" style="color: #6a737d;">    * element like annotations, breaks, loops, imports, etc. In our case,
</span></span><span class="line"><span class="token" style="color: #6a737d;">    * we&amp;#8217;ve defined only call expressions so we override just this one method.
</span></span><span class="line"><span class="token" style="color: #6a737d;">    * Method implementation is pretty straight-forward - it checks if a method
</span></span><span class="line"><span class="token" style="color: #6a737d;">    * that is called has the name we want to avoid and it reports an issue otherwise.
</span></span><span class="line"><span class="token" style="color: #6a737d;">    </span><span class="token" style="color: #6a737d;">*/</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun createUastHandler</span><span class="token">(context</span><span class="token">: </span><span class="token" style="color: #6f42c1;">JavaContext</span><span class="token">)</span><span class="token">: </span><span class="token" style="color: #6f42c1;">UElementHandler</span><span class="token">? </span><span class="token">{
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token" style="color: #d73a49;">object</span><span class="token">: </span><span class="token" style="color: #6f42c1;">UElementHandler</span><span class="token">() {
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">            </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">fun visitCallExpression</span><span class="token">(node</span><span class="token">: </span><span class="token" style="color: #6f42c1;">UCallExpression</span><span class="token">) {
</span></span><span class="line"><span class="token">                </span><span class="token" style="color: #d73a49;">if</span><span class="token"> (node.methodName </span><span class="token" style="color: #d73a49;">!=</span><span class="token"> </span><span class="token" style="color: #005cc5;">null</span><span class="token"> </span><span class="token" style="color: #d73a49;">&amp;&amp;</span><span class="token"> node.methodName</span><span class="token">?.equals</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">setOnClickListener</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">, ignoreCase </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token" style="color: #005cc5;">true</span><span class="token">) </span><span class="token" style="color: #d73a49;">==</span><span class="token"> </span><span class="token" style="color: #005cc5;">true</span><span class="token">) {
</span></span><span class="line"><span class="token">                    context</span><span class="token">.report</span><span class="token">(ISSUE_CLICK_LISTENER, node, context</span><span class="token">.getLocation</span><span class="token">(node), REPORT_MESSAGE, </span><span class="token">createFix</span><span class="token">())
</span></span><span class="line"><span class="token">                }
</span></span><span class="line"><span class="token">            }
</span></span><span class="line"><span class="token">        }
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #6a737d;">/**</span><span class="token" style="color: #6a737d;">
</span></span><span class="line"><span class="token" style="color: #6a737d;">     * Method will create a fix which can be trigger within IDE and
</span></span><span class="line"><span class="token" style="color: #6a737d;">     * it will replace incorrect method with a correct one.
</span></span><span class="line"><span class="token" style="color: #6a737d;">     </span><span class="token" style="color: #6a737d;">*/</span><span class="token">
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">private</span><span class="token"> </span><span class="token">fun createFix</span><span class="token">()</span><span class="token">: </span><span class="token" style="color: #6f42c1;">LintFix</span><span class="token"> </span><span class="token">{
</span></span><span class="line"><span class="token">        </span><span class="token" style="color: #d73a49;">return</span><span class="token"> </span><span class="token">fix</span><span class="token">()</span><span class="token">.replace</span><span class="token">()</span><span class="token">.text</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">setOnClickListener</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">.with</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">setThrottlingClickListener</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)</span><span class="token">.build</span><span class="token">()
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-172"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-170">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-171'
	>
	The last thing we need to do is add issues to our registry and tell Lint there is a custom registry of issues that it should use alongside a default one.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-174"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">class MyIssueRegistry </span><span class="token">: </span><span class="token" style="color: #6f42c1;">IssueRegistry</span><span class="token">() {
</span></span><span class="line"><span class="token">    </span><span class="token" style="color: #d73a49;">override</span><span class="token"> </span><span class="token">val </span><span class="token">issues</span><span class="token">: </span><span class="token" style="color: #6f42c1;">List</span><span class="token">&lt;</span><span class="token" style="color: #6f42c1;">Issue</span><span class="token">&gt; </span><span class="token" style="color: #d73a49;">=</span><span class="token"> </span><span class="token">listOf</span><span class="token">(ISSUE_CLICK_LISTENER)
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-177"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-175">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-176'
	>
	In module’s <code>build.gradle</code>:</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-179"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-code">
	<pre class="phiki language-kotlin github-light" data-language="kotlin" style="background-color: #fff;color: #24292e;"><code><span class="line"><span class="token">jar </span><span class="token">{
</span></span><span class="line"><span class="token">    </span><span class="token">manifest </span><span class="token">{
</span></span><span class="line"><span class="token">        </span><span class="token">attributes</span><span class="token">(</span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">Lint-Registry-v2</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">: </span><span class="token" style="color: #032f62;">&quot;</span><span class="token" style="color: #032f62;">co.infinum.lint.MyIssueRegistry</span><span class="token" style="color: #032f62;">&quot;</span><span class="token">)
</span></span><span class="line"><span class="token">    }
</span></span><span class="line"><span class="token">}
</span></span><span class="line"><span class="token">
</span></span></code></pre></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-182"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-180">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-181'
	>
	where <code>co.infinum.lint</code> is package of <code>MyIssueRegistry</code> class. Now, you can run <code>jar</code> task using <code>gradlew</code> script and library should appear in <code>build/libs</code> directory.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-185"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-183">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-184'
	>
	There is another example of a custom Lint check <a href="https://gist.github.com/mister11/7ff029daae811859f4003814eb19e6ec">here</a> where you can see how to process XML files. The general idea is the same for this as for any other check – extend, specify and override functionality you need for the parts of the code that should be analyzed.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-188"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-186">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-187'
	>
	Usage</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-191"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-189">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-190'
	>
	Your brand new Lint check is ready to be used on a project. If this check can be applied to all projects, you can put it in <code>~/.android/lint</code> folder (you can create it if it doesn’t exist).</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-194"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-192">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-193'
	>
	Also, you can develop your check as a module in your project and include that module as any other dependency using the<code>lintChecks</code> method. This can also be used if you upload the<code>jar</code> file to Bintray.</p></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-197"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-heading" data-id="es-195">
	<h2	class='typography typography--size-52-default js-typography block-heading__heading'
	data-id='es-196'
	>
	Is it worth the trouble?</h2></div>	</div>

<div
	class="wrapper wrapper__use-simple--true"
	data-id="es-200"
	 data-animation='slideFade' data-animation-target='inner-items'>
		
			<div class="block-paragraph" data-id="es-198">
	<p	class='typography typography--size-16-text-roman js-typography block-paragraph__paragraph'
	data-id='es-199'
	>
	Lint is a really nice tool every developer should use. The ability to detect potential issues with your code upfront comes in handy. While custom checks are not the easiest to write, mostly due to the complexity of the API, they’re definitely worth it and can save a lot of time and effort down the road.</p></div>	</div>
</div>
</div>		</div>
	</div><p>The post <a href="https://infinum.com/blog/what-is-android-lint-and-how-helps-write-maintainable-code/">What Is Android Lint and How It Helps Write Maintainable Code</a> appeared first on <a href="https://infinum.com">Infinum</a>.</p>
]]>
				</content:encoded>
			</item>
		
	</channel>
</rss>