Android Studio 提供一个名为 Lint 的代码扫描工具,可帮助您发现并纠正代码结构质量的问题,而无需实际执行该应用,也不必编写测试用例。该工具会报告其检测到的每个问题并提供该问题的描述消息和严重级别,以便您可以快速确定需要优先进行哪些关键改进。此外,您可以调低问题的严重级别,忽略与项目无关的问题,也可以调高严重级别,以突出特定问题。
Lint
工具可检查您的 Android
项目源文件是否包含潜在错误,以及在正确性、安全性、性能、易用性、便利性和国际化方面是否需要优化改进。在使用 Android Studio
时,配置的 Lint
和 IDE
检查会在您每次构建应用时运行。
注:在 Android Studio 中编译代码时,再运行 IntelliJ 代码检查可以简化代码检查。
本文主要包括以下几部分:
一. Lint 工作方式简介
二. Lint 的使用
三. Lint 的相关配置
四. Lint问题种类(常见的)
五. 自定义Lint
一. Lint 如何处理应用源文件
先来看一张图:
- 应用源文件:组成 Android 项目的文件,包括
Java
和XML
文件、图标和 ProGuard 配置文件等。 - lint.xml 文件:此配置文件可用于指定您希望排除的任何
Lint
检查以及自定义问题严重级别。 - Lint 工具:您可以从命令行或在
Android Studio
中对Android
项目运行此静态代码扫描工具。 - Lint 检查结果:可以在控制台或
Android Studio
的Inspection Results
窗口中查看Lint
检查结果。
注:Lint 工具检查可能影响 Android 应用质量和性能的代码结构问题。
强烈建议您先纠正 Lint 检测到的任何错误再发布应用。
二. Lint 的使用
1. 运行 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
: 仅限当前项目中对应模块文件夹中的文件。 - Current File:仅限当前项目中的当前文件。在您已选择文件或文件夹时显示。
- Class Hierarchy:选择此选项并点击 OK,会出现一个对话框,其中显示当前项目中的所有类。使用此对话框中的 Search by Name 字段过滤并选择要检查的类。如果未过滤类列表,代码检查将检查所有类。
- VCS Scopes: VCS 查找范围。
- Custom Scopes:自定义查找范围。
看完了吧,明白其中意思了吧,选择好范围之后点击 OK
,Lint
开始检查。
注:如果想直接看检查结果,可以选择跳过创建自定义范围。
创建自定义范围
点击上图 2
,显示 Scopes
对话框,默认是空的,我们可以点击左上角的+
号新增一个检查范围,这里由于之前我创建过,所以不为空,见下图:
点击左上角
+
号出现
Local
和
Shared
两个选项:
- 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
为每个
定义唯一的 id
属性值。
您可以在
标记中设置严重级别属性,以更改某个问题的严重级别或禁止 Lint
检查此问题。
Lint.xml
文件示例:
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
布局文件的
元素中的 UnusedResources
问题。如果某个父元素声明了 ignore
属性,则该元素的子元素会继承此属性。在本例中,也会禁止 Lint
检查
子元素。
要禁止检查多个问题,请使用以逗号分隔的字符串列出要禁止检查的问题。例如:
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
写成了
logn
,
Lint
默认对拼写错误是个下滑波浪线,很不起眼。我们修改一下。
打开
Preferences
,之后按图所示操作:
右边的
Severity
就是严重程度,改成
Error
,点击
OK
。
好了,现在拼写错误就会出现红色的错误警告了,编译不通过,还不乖乖的去改!!!
四. Lint问题种类(常见的)
- Correctness 不够完美的编码,比如硬编码、使用过时
API
等 - Performanc 对性能有影响的编码,比如:静态引用,循环引用等
- Internationalization 国际化,直接使用汉字,没有使用资源引用等
- Security 不安全的编码,比如在
WebView
中允许使用JavaScriptInterface
等 - Usability 可用的,有更好的替换的 比如排版、图标格式建议
.png
格式 等 - Accessibility 辅助选项,比如
ImageView
的contentDescription
往往建议在属性中定义等 - 其他的结果条目则是针对
Java
语法的问题,另外每一个问题都有区分严重程度(severity)
,从高到底依次是:
Fatal
Error
Warning
Information
Ignore
其中Fatal
和Error
都是指错误,但是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 优化代码、去除多余资源