# Lint使用
Android Studio 提供一個名為 Lint 的代碼掃描工具,可幫助您發現并糾正代碼結構質量的問題,而無需實際執行該應用,也不必編寫測試用例。該工具會報告其檢測到的每個問題并提供該問題的描述消息和嚴重級別,以便您可以快速確定需要優先進行哪些關鍵改進。此外,您可以調低問題的嚴重級別,忽略與項目無關的問題,也可以調高嚴重級別,以突出特定問題。
Lint 工具可檢查您的 Android 項目源文件是否包含潛在錯誤,以及在正確性、安全性、性能、易用性、便利性和國際化方面是否需要優化改進。
下面我們會對lint的使用、定制進行簡單的介紹。
## 一、Lint使用
在使用 Android Studio 時,配置的 Lint 和 IDE 檢查會在您每次構建應用時運行。不過,您可以手動運行檢查或從命令行運行 Lint。 本段會對lint的多種執行方式進行簡述。
### 1.1、實時執行
目前android studio中使用 IDEA的Inspections組件,他會對語法、拼寫進行檢查,Android Studio又在IDEA的Inspection基礎上實現了Lint的實時檢測功能。
在Android Studio中寫代碼時,Inspections會實時執行,其中包括Android定義的Lint規則,并在代碼中直接標為黃色警告或紅色錯誤。還可以使用Andorid Studio的`Intentions`工具快速添加`SupressLint`或自動修復。
> Intentions的使用可參考?[http://www.paincker.com/android-studio-skill](http://www.paincker.com/android-studio-skill)

可在Android Studio的設置中配置代碼實時檢查時,要檢查的項
1. Preference – Editor – Inspections:代碼檢查
2. 默認有Default和Project Default兩套配置,作用范圍分別是全局和當前工程
### 1.2、手動執行
在Android Studio中可從菜單`Analyze - Inspect Code`手動執行Inspections,可選擇要檢查代碼的范圍(Inspection Scope),以及要檢查的問題(Inspection Profile)。執行完成后效果如圖,可以雙擊結果定位有問題的代碼

### 1.3、Gradle Task執行
Gradle中編譯代碼時,會以任務(Task)的形式組織每一步操作,Task之間可以存在依賴關系,執行一個Task前,會先執行它所依賴的Task。
Android的Gradle環境下,有下面幾個常見的Task。
* assemble:Gradle內建的編譯任務
* check:Gradle內建的檢查任務
* test:Gradle內建的測試任務
* build:包含assemble、check、test
* lint:Android插件定義的Lint檢查任務,被包含到check任務中
在命令行中可調用gradle執行Task,例如在命令行中調用`gradle lint`即可執行lint任務。對于某個具體的BuildType(例如Debug)和ProductFlavor(例如Huawei市場),還可以執行`gradle lintHuaweiDebug`只對這種Build版本做Lint檢查。
Lint默認會把所有結果以XML和HTML格式,輸出到`build/reports/lint-results-xxx`中,可以在此查看所有Lint問題,包括具體在哪一行,以及Lint問題對應的ID。

### 1.4、命令行
直接執行`lint`命令,可執行文件位于`<android-home>/tools/lint`(`<android-home>`即AndroidSDK所在目錄)。結果也會輸出到報表中。具體參數配置可以用`lint --help`查看
## 二、Lint配置
使用官方自帶的lint檢查時,目前可用的配置有兩處:LintOptions和lint.xml。
總體可配置的項:可以簡述為以下幾種:
* 配置lint的報告
* 配置lint檢查的具體項目
* 配置lint檢測行為
為了方便后面的述說,這里先貼一下lint.xml和lintOption的簡單示例。
LintOptions常用配置項:
```groovy
android {
lintOptions {
// 如果為 true,生成一個問題的純文本報告(默認為false)
textReport true
// 配置寫入輸出結果的位置;它可以是一個文件或 “stdout”(標準輸出)
textOutput 'stdout'
// 如果為真,會生成一個XML報告,以給Jenkins之類的使用
xmlReport false
// 用于寫入報告的文件(如果不指定,默認為lint-results.xml)
xmlOutput file("lint-report.xml")
// 如果為真,會生成一個HTML報告(包括問題的解釋,存在此問題的源碼,等等)
htmlReport true
// 寫入報告的路徑,它是可選的(默認為構建目錄下的 lint-results.html )
htmlOutput file("lint-report.html")
// 不檢查給定的問題id
disable 'TypographyFractions','TypographyQuotes'
// 檢查給定的問題 id
enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
// * 僅 * 檢查給定的問題 id
check 'NewApi', 'InlinedApi'
// 如果為true,則在錯誤報告的輸出中不包括源代碼行
// 重置 lint 配置(使用默認的嚴重性等設置)。
lintConfig file("default-lint.xml")
// 設置為 true時lint將不報告分析的進度
quiet true
// 如果為 true,則當lint發現錯誤時停止 gradle構建
abortOnError false
// 如果為 true,則只報告錯誤
ignoreWarnings true
// 如果為 true,則當有錯誤時會顯示文件的全路徑或絕對路徑 (默認情況下為true)
//absolutePaths true
// 如果為 true,則檢查所有的問題,包括默認不檢查問題
checkAllWarnings true
// 如果為 true,則將所有警告視為錯誤
warningsAsErrors true
noLines true
// 如果為 true,則對一個錯誤的問題顯示它所在的所有地方,而不會截短列表,等等。
showAll true
// 設置為 true, 將使所有release 構建都以issus的嚴重性級別為fatal(severity=false)的設置來運行lint
// 并且,如果發現了致命(fatal)的問題,將會中止構建(由上面提到的 abortOnError 控制)
checkReleaseBuilds true
// 設置給定問題的嚴重級別(severity)為fatal (這意味著他們將會
// 在release構建的期間檢查 (即使 lint 要檢查的問題沒有包含在代碼中)
fatal 'NewApi', 'InlineApi'
// 設置給定問題的嚴重級別為error
error 'Wakelock', 'TextViewEdits'
// 設置給定問題的嚴重級別為warning
warning 'ResourceAsColor'
// 設置給定問題的嚴重級別(severity)為ignore (和不檢查這個問題一樣)
ignore 'TypographyQuotes'
}
}
```
更多關于lintOption的信息可以查看 [LintOption的官方說明](http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.LintOptions.html)
### 2.1、配置lint的報告
根據上面貼的示例可以看到:
`xmlReport`:lint檢查完成后,是否輸出xml形式的報告。
`xmlOutput file("lint-report.xml")`:用來配置報告輸出到哪里;
后面的`textReport`、`textOutput`、`htmlReport`、`htmlOutput`功能類似,這里不再贅述。
### 2.2、配置lint檢查的具體項目
在實際開發中,官方自帶的一些Issue對我們來說,并沒有那么必要,我們可以通過配置來決定lint過程中,哪些Issus啟用,哪些Issus禁用。
這里主要用到以下幾項來配置相關Issus的開關:
* `enable`:配置要檢查的問題
* `disable`:指定不檢查的問題
* `check`:指定所有要檢查的問題,沒有指定的都不檢查
此外,官方內置Issue項目的警告級別,并不能總是符合實際開發的場景,我們可以通過以下幾個項來重載 相應的警告級別。
* `error`:將相關Issue的級別設置為Error
* `warning`:將相關Issue的級別設置為 warning
* `ignore`:將相關Issue的級別設置為 忽略
* `fatal`:設置相關Issue的嚴重級別(severity)為fatal (這意味著他們將會在release構建的期間檢查 (即使 lint 要檢查的問題沒有包含在代碼中)
### 2.3、配置lint檢測行為
lintOption還可以配置檢查的行為,
* `abortOnError`:現Error級別Lint問題時會中斷編譯
* `ignoreWarnings`:不檢查Warning級別的Lint問題
* `warningsAsErrors`:對Warnning問題會和Error一樣處理
* `checkReleaseBuilds`:Release時檢查fatal級別的問題
除了在LintOption中配置外,還可以載入自定義的配置lint.xml:
`lintConfig`:用來告知編譯器加載指定的lint.xml文件來覆蓋默認的lint配置。
lint.xml示例:
```xml
<?xml version="1.0" encoding="utf-8" ?>
<lint>
<!--配置所有Issue的默認優先級-->
<issue id="all" severity="warning"/>
<!--配置指定Issue的優先級-->
<issue id="ShowToast" severity="error"/>
<!--忽略指定路徑的指定問題,支持正則表達式或path匹配-->
<issue id="NewApi">
<ignore regexp=".*MainActivity.java"/>
<ignore path="**/com/demo/lint/MainActivity.java"/>
<ignore path="res/layout/activation.xml"/>
</issue>
</lint>
```
## 三、lint跳過指定代碼
有時Lint會誤報,或者特定代碼明確不希望或不需要檢查特定Lint問題。此時可使用以下方式來跳過指定java、xml的lint檢測。
### 3.1、配置Lint對Java的檢查
要在 Android 項目中特別禁止 Lint 檢查某個 Java 類或方法,請向此 Java 代碼添加`@SuppressLint` 注解。
下例說明了可以如何對 `onCreate` 方法中的 `NewApi` 問題關閉 Lint 檢查。Lint 工具會繼續檢查該類的其他方法中的 NewApi 問題。
```java
@SuppressLint("NewApi")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
```
下例說明了如何對 `FeedProvider` 類中的 `ParserError` 問題關閉 Lint 檢查:
```java
@SuppressLint("ParserError")
public class FeedProvider extends ContentProvider {}
```
要禁止檢查 Java 文件中的所有 Lint 問題,請使用如下 all 關鍵字:
```java
@SuppressLint("all")
```
### 3.2、配置Lint對XML的檢查
您可以使用 `tools:ignore` 屬性禁止 Lint 檢查 XML 文件的特定部分。在 `lint.xml` 文件中添加以下命名空間值,以便 Lint 工具能識別此屬性:
`namespace xmlns:tools="http://schemas.android.com/tools"`
下例說明了可以如何禁止 Lint 檢查 XML 布局文件的 <LinearLayout> 元素中的 UnusedResources 問題。如果某個父元素聲明了 ignore 屬性,則該元素的子元素會繼承此屬性。在本例中,也會禁止 Lint 檢查 <TextView> 子元素。
```xml
<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>
```
要禁止檢查多個問題,請使用以逗號分隔的字符串列出要禁止檢查的問題。例如:
```xml
tools:ignore="NewApi,StringFormatInvalid"
```
要禁止 Lint 檢查 XML 元素中的所有問題,請使用如下 all 關鍵字:
```xml
tools:ignore="all"
```
## 四、查看所有Issue
android build tools每次大版本更新,都會帶來一些新的lint規則。我們可以通過執行`<android-home>/tools/lint --list`來查看當前支持的所有Issue Id。
```
Valid issue categories:
Correctness
Correctness:Messages
Security
Performance
Usability:Typography
Usability:Icons
Usability
Accessibility
Internationalization
Bi-directional Text
Valid issue id's:
"ContentDescription": Image without contentDescription
"AddJavascriptInterface": addJavascriptInterface Called
"ShortAlarm": Short or Frequent Alarm
"AlwaysShowAction": Usage of showAsAction=always
...
```
## 參考文獻
* [使用 Lint 改進您的代碼](https://developer.android.com/studio/write/lint)
* [Android Lint:基本使用與配置](http://www.paincker.com/android-lint-1-usage)
* [你可能不知道的Android Studio/IDEA使用技巧](http://www.paincker.com/android-studio-skill)
* [Lint Options](http://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.LintOptions.html)
- 計算機基礎
- 簡答1
- 簡答2
- 專案
- 淺談0與1
- 淺談TCP_IP
- 淺談HTTP
- 淺談HTTPS
- 數據結構與算法
- 常見數據結構簡介
- 常用算法分析
- 常見排序算法
- Java數據結構類問題簡答
- 專案
- HashMap
- 淺談二叉樹
- 算法題
- 算法001_TopN問題
- 算法002_漢諾塔
- 編程思想
- 雜說
- 觀點_優秀程序設計的18大原則
- 設計模式_創建型
- 1_
- 2_
- 設計模式_結構型
- 1_
- 2_
- 設計模式_行為型
- 1_
- 2_
- Java相關
- 簡答1
- 簡答2
- 專案
- 淺談String
- 淺談Java泛型
- 淺談Java異常
- 淺談動態代理
- 淺談AOP編程
- 淺談ThreadLocal
- 淺談Volatile
- 淺談內存模型
- 淺談類加載
- 專案_數據結構
- 淺談SpareArray
- Android相關
- Android面試題
- 專案
- 推送原理解析
- Lint
- 自定義Lint
- Lint使用
- 優化案
- Apk體積優化
- Kotlin相關
- 簡答1
- 簡答2
- 三方框架相
- Okhttp3源碼分析
- ButterKnife源碼分析
- Glide4源碼分析
- Retrofit源碼分析
- RxJava源碼分析
- ARouter源碼分析
- LeakCanary源碼分析
- WMRouter源碼分析
- 跨平臺相關
- ReactNative
- Flutter
- Hybrid
- 優質源
- 資訊源
- 組件源
- 推薦