美文网首页
使用 Lint 改进您的代码

使用 Lint 改进您的代码

作者: 沐风雨木 | 来源:发表于2018-12-27 17:29 被阅读19次

Android Studio 提供一个名为 Lint 的代码扫描工具,可帮助您发现并纠正代码结构质量的问题,而无需实际执行该应用,也不必编写测试用例。该工具会报告其检测到的每个问题并提供该问题的描述消息和严重级别,以便您可以快速确定需要优先进行哪些关键改进。此外,您可以调低问题的严重级别,忽略与项目无关的问题,也可以调高严重级别,以突出特定问题。

Lint 工具可检查您的 Android 项目源文件是否包含潜在错误,以及在正确性、安全性、性能、易用性、便利性和国际化方面是否需要优化改进。在使用 Android Studio 时,配置的 LintIDE 检查会在您每次构建应用时运行。

注:在 Android Studio 中编译代码时,再运行 IntelliJ 代码检查可以简化代码检查。
本文主要包括以下几部分:

一. Lint 工作方式简介
二. Lint 的使用
三. Lint 的相关配置
四. Lint问题种类(常见的)
五. 自定义Lint

一. Lint 如何处理应用源文件

先来看一张图:


Lint 工具的代码扫描工作流
  • 应用源文件:组成 Android 项目的文件,包括 JavaXML 文件、图标和 ProGuard 配置文件等。
  • lint.xml 文件:此配置文件可用于指定您希望排除的任何 Lint 检查以及自定义问题严重级别。
  • Lint 工具:您可以从命令行或在 Android Studio 中对 Android 项目运行此静态代码扫描工具。
  • Lint 检查结果:可以在控制台或 Android StudioInspection Results窗口中查看 Lint 检查结果。
注:Lint 工具检查可能影响 Android 应用质量和性能的代码结构问题。
   强烈建议您先纠正 Lint 检测到的任何错误再发布应用。

二. Lint 的使用

1. 运行 Lint

运行 Lint 的方式可以通过下面一张图来说明:

Lint运行方式
Lint 运行方式有两种,从命令行运行 Lint 这种方式咱就不说了,主要说说从 Android Studio 中运行 Lint
由于 Android Studio 中内置了 Lint,所以我们可以这样这样( 工具栏 > Analyze > Inspect Code),明白了吧。
之后出现 Specify Inspection Scope 对话框,在对话框中查看设置。

默认是检查整个项目,其他两个单选项可以查看图上标注提示,这里我们选择 Custom scope 自定义检查范围,之后我们可以点击下图中 1,出现如下选项:

选择要使用的自定义范围
  • Project Files:当前项目中的所有文件。
  • Project Production Files:仅限当前项目中的生产文件。
  • Project Test Files:仅限当前项目中的测试文件。请参阅测试类型和位置
  • Open Files:仅限当前项目中已打开的文件。
  • Module <your-module>:仅限当前项目中对应模块文件夹中的文件。
  • Current File:仅限当前项目中的当前文件。在您已选择文件或文件夹时显示。
  • Class Hierarchy:选择此选项并点击 OK,会出现一个对话框,其中显示当前项目中的所有类。使用此对话框中的 Search by Name 字段过滤并选择要检查的类。如果未过滤类列表,代码检查将检查所有类。
  • VCS Scopes: VCS 查找范围。
  • Custom Scopes:自定义查找范围。

看完了吧,明白其中意思了吧,选择好范围之后点击 OKLint 开始检查。

注:如果想直接看检查结果,可以选择跳过创建自定义范围。

创建自定义范围

点击上图 2 ,显示 Scopes 对话框,默认是空的,我们可以点击左上角的+ 号新增一个检查范围,这里由于之前我创建过,所以不为空,见下图:


点击左上角 + 号出现 LocalShared 两个选项:
  • Local:只能当前项目使用;
  • Shared:其他 Android Studio 项目也可以使用。

选择其中一个出现命名对话框,为范围命名,如 randyLint 并点击 OK
展开项目文件夹,选择您要添加到自定义范围中的项,然后点击右侧的按钮之一。

自定义范围

右侧按钮表示要操作的类型:

  • Include:包含此文件夹及其文件,但不包含其子文件夹中的任何文件。
  • Include Recursively:包含此文件夹及其所有文件,以及子文件夹及其中的文件。
  • Exclude:排除此文件夹及其文件,但不排除其子文件夹中的任何文件。
  • Exclude Recursively:排除此文件夹及其所有文件,以及子文件夹及其中的文件。

这里我选择的是整个 app 文件夹下的内容,可以看到 app 下的文件都变绿了,总共有 3791 个文件夹要扫描。。
点击 OK 返回上一个对话框,在点击 OK 开始检查,

检查结果处理

检查完毕后会弹出 Inspection 的控制台,并在其中列出详细的检查结果:

检查结果
这是我修改了一些之后的结果,有些问题没有显示出来,那么看下面一张神图(如果看截图不方便可以看标题 四.Lint问题种类):

望眼看过去,这么多,被吓到不知所措了是不是,我第一次接触的时候完全不知道从哪里入手,那就借用别人的一张图:
别人的检查结果
我们主要关注红框内的警告,先来看看我的代码 Performance 有什么问题:

在借用别人的一句话“没想到我还有这么多进步空间!Lint 真是神器,可以帮我们发现自己忽略或者没有意识到的问题,尤其是性能方面,如果你觉得自己代码想优化又不知道从何做起,不妨让 Lint 给你指指路。”
好了,之后那就改吧~

三. Lint 的相关配置

1. 配置 Lint 文件

对于执行 Lint 操作的相关配置,是定义在 gradle 文件的 lintOptions 中,可定义的选项及其默认值:

android {
    lintOptions {
        // 设置为 true,则当 Lint 发现错误时停止 Gradle 构建
        abortOnError false
        // 设置为 true,则当有错误时会显示文件的全路径或绝对路径 (默认情况下为true)
        absolutePaths true
        // 仅检查指定的问题(根据 id 指定)
        check 'NewApi', 'InlinedApi'
        // 设置为 true 则检查所有的问题,包括默认不检查问题
        checkAllWarnings true
        // 设置为 true 后,release 构建都会以 Fatal 的设置来运行 Lint。
        // 如果构建时发现了致命(Fatal)的问题,会中止构建(具体由 abortOnError 控制)
        checkReleaseBuilds true
        // 不检查指定的问题(根据问题 id 指定)
        disable 'TypographyFractions','TypographyQuotes'
        // 检查指定的问题(根据 id 指定)
        enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
        // 在报告中是否返回对应的 Lint 说明
        explainIssues true
        // 写入报告的路径,默认为构建目录下的 lint-results.html
        htmlOutput file("lint-report.html")
        // 设置为 true 则会生成一个 HTML 格式的报告
        htmlReport true
        // 设置为 true 则只报告错误
        ignoreWarnings true
        // 重新指定 Lint 规则配置文件
        lintConfig file("default-lint.xml")
        // 设置为 true 则错误报告中不包括源代码的行号
        noLines true
        // 设置为 true 时 Lint 将不报告分析的进度
        quiet true
        // 覆盖 Lint 规则的严重程度,例如:
        severityOverrides ["MissingTranslation": LintOptions.SEVERITY_WARNING]
        // 设置为 true 则显示一个问题所在的所有地方,而不会截短列表
        showAll true
        // 配置写入输出结果的位置,格式可以是文件或 stdout
        textOutput 'stdout'
        // 设置为 true,则生成纯文本报告(默认为 false)
        textReport false
        // 设置为 true,则会把所有警告视为错误处理
        warningsAsErrors true
        // 写入检查报告的文件(不指定默认为 lint-results.xml)
        xmlOutput file("lint-report.xml")
        // 设置为 true 则会生成一个 XML 报告
        xmlReport false
        // 将指定问题(根据 id 指定)的严重级别(severity)设置为 Fatal
        fatal 'NewApi', 'InlineApi'
        // 将指定问题(根据 id 指定)的严重级别(severity)设置为 Error
        error 'Wakelock', 'TextViewEdits'
        // 将指定问题(根据 id 指定)的严重级别(severity)设置为 Warning
        warning 'ResourceAsColor'
        // 将指定问题(根据 id 指定)的严重级别(severity)设置为 ignore
        ignore 'TypographyQuotes'
    }
}

我们还可以在 lint.xml 文件中指定 Lint 检查首选项。如果您是手动创建此文件,请将其置于 Android 项目的根目录,Android Lint会自动识别该文件。在执行检查时按照 lint.xml 的内容进行检查。如上面提到的那样,开发者也可以通过 lintOptions 中的 lintConfig 选项来指定配置文件。

lint.xml 文件由封闭的 <lint> 父标记组成,此标记包含一个或多个 <issue> 子元素。Lint 为每个 <issue> 定义唯一的 id 属性值。

<?xml version="1.0" encoding="UTF-8"?>
    <lint>
        <!-- list of issues to configure -->
</lint>

您可以在 <issue> 标记中设置严重级别属性,以更改某个问题的严重级别或禁止 Lint 检查此问题。
Lint.xml 文件示例:

<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <!-- Disable the given check in this project -->
    <issue id="IconMissingDensityFolder" severity="ignore" />

    <!-- Ignore the ObsoleteLayoutParam issue in the specified files -->
    <issue id="ObsoleteLayoutParam">
        <ignore path="res/layout/activation.xml" />
        <ignore path="res/layout-xlarge/activation.xml" />
    </issue>

    <!-- Ignore the UselessLeaf issue in the specified file -->
    <issue id="UselessLeaf">
        <ignore path="res/layout/main.xml" />
    </issue>

    <!-- Change the severity of hardcoded strings to "error" -->
    <issue id="HardcodedText" severity="error" />
</lint>
2. 配置 Lint 对 Java 和 XML 源文件的检查

我们可以禁止 Lint 检查 Java 和 XML 源文件。

提示:您可以在 Default Preferences 对话框中管理 Lint 检查 Java 或 XML 源文件的功能。
选择 File > Other Settings > Default Settings,然后在 Default Preferences 对话框的左侧窗格中选择 Editor > Inspections。

配置 Lint 对 Java 的检查

要在 Android 项目中特别禁止 Lint 检查某个 Java 类或方法,请向此 Java 代码添加 @SuppressLint 注解。

下例说明了可以如何对 onCreate 方法中的 NewApi 问题关闭 Lint 检查。Lint 工具会继续检查该类的其他方法中的 NewApi 问题。

@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

下例说明了如何对 FeedProvider 类中的 ParserError 问题关闭 Lint 检查:

@SuppressLint("ParserError")
public class FeedProvider extends ContentProvider {

要禁止检查 Java 文件中的所有 Lint 问题,请使用如下 all 关键字:

@SuppressLint("all")

配置 Lint 对 XML 的检查

您可以使用 tools:ignore 属性禁止 Lint 检查 XML 文件的特定部分。在 lint.xml 文件中添加以下命名空间值,以便 Lint 工具能识别此属性:

namespace xmlns:tools="http://schemas.android.com/tools"

下例说明了可以如何禁止 Lint 检查 XML 布局文件的 <LinearLayout> 元素中的 UnusedResources 问题。如果某个父元素声明了 ignore 属性,则该元素的子元素会继承此属性。在本例中,也会禁止 Lint 检查 <TextView> 子元素。

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    tools:ignore="UnusedResources" >

    <TextView
        android:text="@string/auto_update_prompt" />
</LinearLayout>

要禁止检查多个问题,请使用以逗号分隔的字符串列出要禁止检查的问题。例如:

tools:ignore="NewApi,StringFormatInvalid"

要禁止 Lint 检查 XML 元素中的所有问题,请使用如下 all 关键字:

tools:ignore="all"

团队中建立代码规范利器:提升、降低问题的等级

虽然 Lint 可以帮我们检查代码的问题,但多人合作时,我们更期望可以在写代码时就发现问题、解决问题。

鉴于团队成员中水平良莠不齐,靠个人意识有时候很难保证质量,这时可以修改 Lint 对于特定问题的警告等级,以最直观的 IDE 提示来警醒成员。
Lint 的警告严重程度有以下几种:

  • Error:错误,最显眼的一个
  • Blocker:阻塞剂,显眼
  • Critical:关键,略微显眼一点
  • Major:重大,略微显眼一点
  • Warning:警告,略微显眼一点
  • Weak Warning:比较弱的警告,提示比较弱
  • Server Problem:服务器错误?好像不是
  • Typo:拼写错误,绿色波浪下划线,也不太起眼
  • No highlighting:没有使用的属性,灰色,很不起眼

日常开发中,好一点的程序员会关注 Warning 的警告,根据警告优化代码,但那也只是很少一部分。但是红色的 Error 就不一样了,基本上看到就想要消灭掉(不消灭也运行不了,xiha~!)。
我们拿命名拼写错误举个例子:
默认的拼写错误是 Typo ,提示很弱,所以常被人忽略:


上面的 String 类型变量 login 写成了 lognLint 默认对拼写错误是个下滑波浪线,很不起眼。我们修改一下。
打开 Preferences,之后按图所示操作:
右边的 Severity 就是严重程度,改成 Error,点击 OK

好了,现在拼写错误就会出现红色的错误警告了,编译不通过,还不乖乖的去改!!!

四. Lint问题种类(常见的)

  • Correctness 不够完美的编码,比如硬编码、使用过时 API
  • Performanc 对性能有影响的编码,比如:静态引用,循环引用等
  • Internationalization 国际化,直接使用汉字,没有使用资源引用等
  • Security 不安全的编码,比如在 WebView 中允许使用 JavaScriptInterface
  • Usability 可用的,有更好的替换的 比如排版、图标格式建议 .png 格式 等
  • Accessibility 辅助选项,比如 ImageViewcontentDescription 往往建议在属性中定义等
  • 其他的结果条目则是针对 Java 语法的问题,另外每一个问题都有区分严重程度(severity),从高到底依次是:
    Fatal
    Error
    Warning
    Information
    Ignore
    其中 FatalError 都是指错误,但是 Fatal 类型的错误会直接中断 ADT 导出 APK,更为严重。
    在结果列表中点击一个条目,可以看到详细的源文件名和位置,以及命中的错误规则(issue)、解决方案或者屏蔽提示
    除了直接在菜单中运行 Lint 外,大部分问题代码在编写时 Android Studio 就会给出提醒。

检查问题列表详见 点我跳转

一. Android

1. Correctness 

1) Appcompat Custom Widgets
  Appcompat自定义小部件一般会让你继承自 android.support.v7.widget.AppCompat...
  不要直接扩展android.widget类,而应该扩展android.support.v7.widget.AppCompat中的一个委托类。
2) Attribute unused on older versions
  旧版本未使用的属性  针对具有minSdkVersion
  这不是一个错误; 应用程序将简单地忽略该属性。
  可以选择在layout-vNN文件夹中创建一个布局的副本 将在API NN或更高版本上使用,您可以利用更新的属性。
3) Class is not registered in the manifest
  类未在清单中注册
  Activities, services and content providers should be registered in the AndroidManifest.xml file
4) Combining Ellipsize and Maxlines
  Ellipsize和Maxlines相结合
  结合ellipsize和maxLines = 1可能导致某些设备崩溃。 早期版本的lint建议用maxLines = 1替换singleLine = true,但在使用ellipsize时不应该这样做
5) Extraneous text in resource files
  资源文件中的无关文本
6) Hardcoded reference to /sdcard
  硬编码参考/ SD卡
  代码不应该直接引用/ sdcard路径; 而是使用:Environment.getExternalStorageDirectory().getPath()
  不要直接引用/ data / data /路径; 它可以在多用户场景中有所不同。
7) Implied default locale in case conversion
  在转换的情况下默认的默认语言环境
8) Implied locale in date format
  隐含的日期格式的区域设置
  调用者都应该使用getDateInstance(),getDateTimeInstance()或getTimeInstance()来获得适合用户语言环境的SimpleDateFormat的现成实例。
9) Likely cut & paste mistakes
  可能剪切和粘贴错误
  剪切和粘贴调用findViewById但忘记更新R.id字段的情况。 有可能你的代码只是(冗余)重复查找字段
10) Mismatched Styleable/Custom View Name
  不匹配的样式/自定义视图名称
  自定义视图的惯例是使用名称与自定义视图类名称相匹配的声明样式。
11) Missing Permissions
  缺少权限
12) Nested scrolling widgets
  嵌套的滚动小部件
  A scrolling widget such as a ScrollView should not contain any nested scrolling widgets since this has various usability issues
13) Obsolete Gradle Dependency    
  已过时的Gradle依赖关系
14) Target SDK attribute is not targeting latest version    
  目标SDK属性未定位到最新版本
15) Using 'px' dimension    
  使用“px”维度
16) Using android.media.ExifInterface    
  使用android.media.ExifInterface旧版的有一些漏洞,使用支持库中的
17) Using dp instead of sp for text sizes    
  使用dp代替文本大小的sp
18) Using Private APIs    
  使用私有API
19) Using private resources    
  使用私人资源

2. Internationalization

1) Hardcoded text  
  硬编码文本
  直接在布局文件中对文本属性进行硬编码是有缺陷的
  should use @string resource
2) Overlapping items in RelativeLayout  
  在RelativeLayout中重叠项目
  如果相对布局的文本或按钮项左右对齐,则由于本地化的文本扩展,它们可以相互重叠,除非它们具有toEndOf / toStartOf之类的相互约束。
3) Padding and margin symmetry   
  填充和边缘对称
  如果您在布局的左侧指定填充或边距,则应该也可以在右侧指定填充(反之亦然),以便从右到左布局对称。
4) TextView Internationalization   
  TextView国际化
  永远不要调用Number#toString()来格式化数字; 它不会正确处理分数分隔符和区域特定的数字
  使用具有适当格式规范(%d或%f)的String#格式
  不要传递字符串(例如“Hello”)来显示文本。 硬编码文本无法正确翻译成其他语言,考虑使用Android资源字符串
  不要通过连接文本块来构建消息。 这样的消息不能被正确翻译。
5) Using left/right instead of start/end attributes   
  使用左/右而不是开始/结束属性

3. Performance

1) Handler reference leaks
  handler导致的泄漏
  由于该Handler被声明为内部类,所以可以防止外部类被垃圾收集。 如果处理程序对主线程以外的线程使用Looper或MessageQueue,则不存在问题。 如果处理程序正在使用主线程的Looper或MessageQueue,则需要修复Handler声明,
  解决:将Handler声明为静态类; 在外部类中,实例化WeakReference到外部类,并在实例化Handler时将此对象传递给Handler; 使用WeakReference对象来引用外部类的所有成员。
2) HashMap can be replaced with SparseArray
  HashMap可以用SparseArray替换
  对于键类型为integer的映射,使用Android SparseArray API通常效率更高。
3) Inefficient layout weight
  低效的布局权重
  当LinearLayout中只有一个控件定义了一个权重时,为它指定一个0dp的宽度/高度会更有效率,因为它将吸收所有的剩余空间。 如果声明的宽度/高度为0dp,则不必首先测量其自己的大小。
4) Layout has too many views
  布局有太多的意见
  在单个布局中使用太多的视图对性能不利。 考虑使用复合绘图或其他技巧来减少此布局中的视图数量。 最大视图数量默认为80,但可以使用环境变量ANDROID_LINT_MAX_VIEW_COUNT进行配置。
5) Layout hierarchy is too deep
  布局层次太深
  嵌套太多的布局对性能不利。 考虑使用更平坦的布局(比如RelativeLayout或GridLayout)。默认的最大深度是10,但可以使用环境变量ANDROID_LINT_MAX_DEPTH进行配置。
6) Memory allocations within drawing code
  内存分配在绘图代码
  应该避免在绘图或布局操作中分配对象。 这些被频繁地调用,所以平滑的UI可以被对象分配造成的垃圾收集暂停中断。 通常处理的方式是预先分配所需的对象,并为每个绘图操作重新使用它们。 有些方法代表您分配内存(如Bitmap.create),并且应该以相同的方式处理这些内存。
7) Missing @Keep for Animated Properties
  属性动画缺少@Keep
  当你使用属性动画师时,属性可以通过反射来访问。 这些方法应该使用@Keep注释,以确保在发布构建期间,这些方法不会被视为未被使用和删除,或者被视为内部的,并被重新命名为更短。 这个检查还会标记出其他可能遇到的反射问题,比如缺少属性,错误的参数类型等等。
8) Missing baselineAligned attribute    
  缺少baselineAligned属性
  当使用LinearLayout在嵌套布局之间按比例分配空间时,应关闭基线对齐属性以使布局计算速度更快。
9) Node can be replaced by a TextView with compound drawables
  节点可以用复合可绘制的TextView替换
  包含ImageView和TextView的LinearLayout可以更有效地处理为复合可绘制(单个TextView,使用drawableTop,drawableLeft,drawableRight和/或drawableBottom属性在文本旁边绘制一个或多个图像)。 如果这两个小部件彼此之间有空白,则可以用drawablePadding属性替换。
10) Obsolete layout params
  过时的布局参数
11) Obsolete SDK_INT Version Check
  已过时的SDK_INT版本检查
  此检查标志版本检查不是必需的,因为minSdkVersion(或周围已知的API级别)已经至少与检查的版本一样高。
  它还会在-vNN文件夹中查找资源,如版本限定符小于或等于minSdkVersion的values-v14,其中内容应合并到最佳文件夹中。
12) Static Field Leaks
  静态常量--持有fragment及activity的引用
  非静态内部类对其外部类具有隐式引用。
  如果该外部类是例如fragment或activity,如果长时间运行的处理程序/加载程序/任务将持有对该activity的引用,长时间没有被回收掉。
13) Useless parent layout
  无用的父母布局
  有没有兄弟的孩子的布局不是滚动视图或根布局,并且没有背景,可以被移除并且其子节点直接移动到父节点以获得更平坦和更高效的布局分层结构。
14) View Holder Candidates
  查看持有人候选人
  Should use View Holder pattern

4. Security

1) Cipher.getInstance with ECB
  Cipher.getInstance与ECB
  不应使用ECB作为cipher mode或不设置cipher mode来调用Cipher#getInstance,因为android上的默认模式是ECB,这是不安全的。(加解密)
2) Content provider does not require permission
  内容提供者不需要权限
  内容提供程序默认导出,系统上的任何应用程序都可能使用它们来读取和写入数据。 如果内容提供者提供对敏感数据的访问,则应该通过在清单中指定export = false来保护它,或者通过可以授予其他应用程序的权限来保护它。
3) Exported service does not require permission
  导出的服务不需要权限
  导出的服务(设置了exported = true或者包含intent-filter并且不指定exported = false的服务)应该定义一个实体为了启动服务或绑定到服务而必须拥有的权限。 没有这个,任何应用程序都可以使用此服务。
4) Hardware Id Usage
  硬件ID使用情况
  不建议使用这些设备标识符,除了高价值欺诈预防和高级电话使用情况。
  getLine1Number获取手机号,getDeviceId设备IMEI,getMacAddressMAC地址
5) Incorrect constant
  不正确的常量
6) Insecure TLS/SSL trust manager
  不安全的TLS / SSL信任管理器
7) Missing @JavascriptInterface on methods
  缺少@JavascriptInterface方法
8) openFileOutput() or similar call passing MODE_WORLD_READABLE
  openFileOutput()或类似的调用传递MODE_WORLD_READABLE
9) openFileOutput() or similar call passing MODE_WORLD_WRITEABLE
  openFileOutput()或类似的调用传递MODE_WORLD_WRITEABLE
  在某些情况下,应用程序可以编写世界可写文件,但应仔细检查这些文件以确保它们不包含私人数据,并且如果文件被恶意应用程序修改,则不会欺骗或破坏应用程序。
10) Receiver does not require permission
  接收者不需要许可
11) Using setJavaScriptEnabled  使用setJavaScriptEnabled
  如果您不确定您的应用程序确实需要JavaScript支持,那么您的代码不应该调用setJavaScriptEnabled。

5. Usability

1) Button should be borderless
  按钮应该是无边界的
  两个 Buttons 放在一个布局里会被判断为按钮栏,需要添加样式取消它的边框
  在 Buttons 上添加属性 style="?android:attr/buttonBarButtonStyle" 。系统提示也可以在按钮的父布局上添加 style="? android:attr/buttonBarStyle" 属性
2) Ellipsis string can be replaced with ellipsis character
  省略号字符串可以用省略号字符替换
  Replace "..." with ellipsis character (…, …) ?
3) Hyphen can be replaced with dash
  连字符可以用短划线代替
  Replace "-" with an "en dash" character (–, –) ?
4) Missing View constructors for XML inflation
  缺少XML通货膨胀的视图构造函数
5) Text size is too small
  文字太小
  避免使用小于12sp的尺寸。小于12sp的字体会太小导致用户看不清

二. 其他类型
  Class structure 类结构
  Code maturity issues 代码成熟度问题
  Code style issues 代码样式问题
  Compiler issues 编译器问题
  Control flow issues 控制流量问题
  Data flow issues 数据流问题
  Declaration redundancy 声明冗余
  Error handling 错误处理
  General 一般
  Imports 进口
  J2ME issues J2ME问题
  Java 5 Java 5
  Java 7 Java 7
  Java language level migration aids Java语言级别的迁移辅助
  Javadoc issues Javadoc问题
  Naming conventions 命名约定
  Numeric issues 数字问题
  Performance issues 性能问题
  Probable bugs 可能的错误
  Properties Files 属性文件
  Spelling 拼字
  Style 样式
  Verbose or redundant code constructs 详细或冗余的代码结构
  XML XML
1. Class structure
  Field can be local字段可以是本地的
  Parameter can be local参数可以是本地的
  'private' method declared 'final'
  'static' method declared 'final'
2. Code maturity issues 代码成熟度问题
  Deprecated API usage不推荐使用API
  Deprecated member is still used不推荐使用的成员仍在使用
3. Code style issues 代码样式问题
  Unnecessary enum modifier不必要的枚举修饰符
  Unnecessary interface modifier不必要的界面修饰符
  Unnecessary semicolon不必要的分号
  private  public
4. Compiler issues 编译器问题
  Unchecked warning未经检查的警告
5. Control flow issues 控制流问题
  Double negation 双重否定
  Pointless boolean expression 无意义的布尔表达式
  Redundant 'if' statement 冗余“if”语句
  Redundant conditional expression 冗余的条件表达式
  Simplifiable boolean expression 简化布尔表达式
  Simplifiable conditional expression 简化条件表达式
  Unnecessary 'return' statement 不必要的“return”声明
  return;
6. Data flow issues 数据流问题
  Boolean method is always inverted布尔方法总是倒置的
  Redundant local variable冗余局部变量
7. Declaration redundancy 声明冗余
  Access static member via instance reference通过实例引用访问静态成员
  this.minsize = this.maxsize;
  Actual method parameter is the same constant实际的方法参数是相同的常量
  Actual value of parameter ''register'' is always ''true''
  Declaration access can be weaker声明访问权限可以再弱
  Can be private
  Declaration can have final modifier宣言可以有最终的修改
  Duplicate throws重复抛出
  Empty method空方法
  Method can be void方法可以是无效的
  Method returns the same value方法返回相同的值
  All implementations of this method always return '3'
  Redundant throws clause冗余抛出子句
  The declared exception 'UnsupportedEncodingException' is never thrown
  Unnecessary module dependency不必要的模块依赖
  Unused declaration未使用的声明(方法,变量)
8. Error handling 错误处理
  Caught exception is immediately rethrown捕获到的异常立即被重新抛出
  Empty 'catch' block空'catch'块
  'return' inside 'finally' block在'finally'块中'返回'
  'throw' inside 'finally' block在“finally”块内“抛出”
9. General
  Annotator注解者
  Default File Template Usage默认文件模板的用法
10. Imports 导入
  Unused import没有用到的导入
11. J2ME issues J2ME问题
  'if'语句可以用&&或||代替 表达
12. Java 5 Java 5
  'for' loop replaceable with 'foreach''for'循环可替换为'foreach'
  'indexOf()' expression is replaceable with 'contains()''indexOf()'表达式可以用'contains()'来替换
  'StringBuffer' may be 'StringBuilder''StringBuffer'可能是'StringBuilder'
  Unnecessary boxing不必要的装箱
  Unnecessary unboxing不必要的拆箱
  'while' loop replaceable with 'foreach''while'循环可以替换'foreach'
13. Java 7 Java 7
  Explicit type can be replaced with <>显式类型可以用<>来替换
  '试试最后'用资源替换'试用'
14. Java language level migration aids Java语言级别的迁移辅助
  'if' replaceable with 'switch'
15. Javadoc issues Javadoc问题
  Dangling Javadoc comment 摇摇晃晃的Javadoc评论
  Declaration has Javadoc problems 宣言有Javadoc问题
  Declaration has problems in Javadoc  声明在Javadoc引用中有问题
16. Naming conventions 命名约定
17. Numeric issues 数字问题
  数字溢出 Numeric overflow
  八进制整数 Octal integer
  无意义的算术表达式 Pointless arithmetic expression
18. Performance issues 性能问题
  Redundant 'String.toString()'  冗余'String.toString()'
  Redundant 'substring(0)' call  冗余'substring(0)'调用
  Redundant call to 'String.format()'  冗余调用'String.format()'
  String concatenation as argument to 'StringBuffer.append()' call  字符串连接  作为“StringBuffer.append()”调用的参数
  String concatenation in loop  循环中的字符串连接
  'StringBuffer' can be replaced with 'String'  'StringBuffer'可以替换为'String'
19. Probable bugs 可能的错误
  Collection added to self   Collection添加到自我
  Constant conditions & exceptions 不变的条件和例外
  Mismatched query and update of collection 不匹配的查询和集合更新
  Mismatched query and update of StringBuilder 不匹配的查询和更新的StringBuilder
  @NotNull/@Nullable problems @NotNull / @可空问题
  Result of method call ignored 方法调用的结果被忽略
  Statement with empty body 声明与空的实现
  String comparison using '==', instead of 'equals()' 使用'=='进行字符串比较,而不是'equals()'
  Suspicious collections method calls 可疑collections方法调用
  Suspicious variable/parameter name combination 可疑变量/参数名称组合
  Unused assignment 没用的赋值操作
20. Properties Files 属性文件
  Unused Property未使用的属性
21. Spelling 拼字
22. Style 样式
  Unnecessary semicolon没必要的分号
23. Verbose or redundant code constructs 详细或冗余的代码结构
  Redundant array creation创建冗余阵列
  Redundant type cast冗余类型转换
24. XML XML
  Deprecated API usage in XML  在XML中不推荐使用API
  Unbound XML namespace prefix  未绑定的XML名称空间前缀
  Unused XML schema declaration  未使用的XML模式声明
  XML highlighting  XML突出显示
  XML tag empty body  XML标签为空的正文

五.自定义Lint

如果发现系统自带的 Lint 检测的 Issue 不满足团队内部的特定需求,可以尝试去自定义Lint规则,自定义 Lint 这里就不再介绍了,感兴趣的朋友可以参考:
Android Studio 工具:Lint 代码扫描工具(含自定义lint)
【我的Android进阶之旅】Android自定义Lint实践

最后,参考链接:

Improve your code with lint checks
Android Studio 工具:Lint 代码扫描工具(含自定义lint)
Android 性能优化:使用 Lint 优化代码、去除多余资源

相关文章

网友评论

      本文标题:使用 Lint 改进您的代码

      本文链接:https://www.haomeiwen.com/subject/yprklqtx.html