提供代碼質量之靜態代碼檢查
前言
在團隊Android項目開發過程中,難免會出現一些比較不容易發現,但是又比較低級的bug。而且因為每個開發人員的編碼習慣不同,寫出的代碼也會有差異。為了保證團隊開發中代碼的規范以及盡量避免低級bug,我們往往需要一些工具來進行嚴格的檢查。下面將介紹在項目中用到的四種插件 lint 、 findBugs 、 PMD 、 CheckStyles 的功能和使用方式,以及如何將多個插件整合在一起,在方便使用的同時盡量做到與項目工程解耦。
一、lint
Lint是Android Studio提供的一個代碼檢測工具,通過它開發者不用運行或者寫測試代碼,就可以發現和糾正問題,優化代碼結構。每個被檢測到的問題,都會生成一條描述信息并指明相應的嚴重性級別,當然這個嚴重性級別我們也可以自己設置的。
檢測范圍
- 潛在的bug
- 可優化的代碼
- 安全性
- 性能
- 可用性
- 可訪問性
-
國際化
插件安裝
Android Studio自帶,無需安裝。
插件使用
通過Gradle運行lint
在工程的根目錄下運行相應的gradle task。
- Windows
gradle lint
- Linux 或者 MAC
./gradlew lint
當運行上面的命令執行完后,就會在項目目錄/app/build/outputs/lint-results-debug.html生成相應的文件,可用瀏覽器打開查看。
手動運行lint
有時我們可能只針對某個文件或者某個目錄進行檢測,這時使用gradle的方式就比較麻煩了,所以Android Studio提供給我們手動運行lint的方式。
- 在AS的工程下選擇module、目錄或者文件
- 右鍵選擇 Analyze > Inspect Code.
-
此時會出現一個選擇“指定檢測范圍”的dialog
-
配置完成后,點擊 OK 按鈕,進行檢測。檢測結果如下圖所示,左邊是檢測類型的樹形結構,右邊則展示詳細的信息。
注:詳細的使用,請看官網文檔 Improve Your Code with Lint
二、findBugs
FindBugs是一個Java靜態分析工具,用來檢查類或者jar文件,用來發現可能的問題。檢測完成之后會生成一份詳細的報告,借助這份報告可以找到潛在的bug,比如NullPointException,特定的資源沒有關閉,查詢數據庫沒有調用Cursor.close()等
檢測范圍
- 常見代碼錯誤,序列化錯誤
- 可能導致錯誤的代碼,如空指針引用
- 國際化相關問題:如錯誤的字符串轉換
- 可能受到的惡意攻擊,如訪問權限修飾符的定義等
- 多線程的正確性:如多線程編程時常見的同步,線程調度問題。
- 運行時性能問題:如由變量定義,方法調用導致的代碼低效問題
插件安裝
在Android Studio中選擇 Preferences -> Plugins ,輸入查找findBugs進行插件安裝。
插件使用
在build.gradle文件中,按照下面步驟進行設置:
- 添加plugin apply plugin:'findbugs'
- 定義任務,指定輸出格式
task findbugs(type: FindBugs, dependsOn: "assembleDebug") {
ignoreFailures = true
effort = "max"
reportLevel = "high"
excludeFilter = new File("$configDir/findbugs/findbugs-filter.xml")
classes = files("${project.rootDir}/app/build/intermediates/classes")
source 'src'
include '**/*.java'
exclude '**/gen/**'
reports {
xml.enabled = false
html.enabled = true
xml {
destination "$reportsDir/findbugs/findbugs.xml"
}
html {
destination "$reportsDir/findbugs/findbugs.html"
}
}
classpath = files()
}</code></pre>
這里要注意因為findBugs是檢查class文件,所以在定義task的時候,我們是 dependsOn: "assembleDebug" ,確保運行findbugs的task能夠成功檢測。
通過 gradle findbugs 方式,在工程目錄下運行命令,檢測完成后,會在制定的目錄下生成報告文檔。文檔支持xml和html兩種格式,本文設置的是html格式,可以直接用瀏覽器打開。
當然,和lint一樣,findBugs也支持手動檢測的方式。在工程里,右鍵 FindBugs -> (選擇檢測的范圍) 。檢測完之后,底部工具欄會跳到 FindBugs-IEDA 下,如圖所示。

三、PMD
PMD是一個很有用的工具,它跟Findbugs類似,但是它不是檢測字節碼,它是直接檢測源代碼。它使用靜態分析來發現錯誤。為什么要將它們同時使用呢?因為它們的檢測方法不同,可以取到互補的作用。
檢測范圍
- 可能的bug——空的try/catch/finally/switch塊。
- 無用代碼(Dead code):無用的本地變量,方法參數和私有方法。
- 空的if/while語句。
- 過度復雜的表達式——不必要的if語句,本來可以用while循環但是卻用了for循環。
- 可優化的代碼:浪費性能的String/StringBuffer的使用。
插件安裝
同樣可以通過AS的plugin進行安裝,推薦安裝QAPlug-PMD。

插件使用
在build.gradle文件中進行如下配置
- 導入Plugin: apply plugin: 'pmd'
- Task配置
task pmd(type: Pmd) {
ignoreFailures = false
ruleSetFiles = files("$configDir/pmd/pmd-ruleset.xml")
ruleSets = []
source 'src'
include '**/*.java'
exclude '**/gen/**'
exclude 'androidTest/**'
exclude 'test/**'
reports {
xml.enabled = false
html.enabled = true
xml {
destination "$reportsDir/pmd/pmd.xml"
}
html {
destination "$reportsDir/pmd/pmd.html"
}
}
}</code></pre>
四、CheckStyles
這個工具用來自動檢測java源碼。啟動之后,可以按照制定的規則對java源碼進行檢查,被將所有的不符合規范的地方生成報告通知給你。
檢測范圍
- 注解
- javadoc注釋
- 命名規范
- 文件頭
- 導入包規范
- 尺寸設置
- 空格
- 正則表達式
- 修飾符
- 代碼塊
- 編碼問題
- 類設計問題
- 重復、度量以及一些雜項
總而言之,是一些代碼規范問題!!
插件安裝
通過AS的Plugin進行安裝

插件使用
- 導入Plugin
apply plugin: 'checkstyle'
- 設置CheckStyle的版本
checkstyle {
toolVersion '6.1.1'
showViolations true
}
- 配置任務
task checkstyle(type: Checkstyle) {
configFile file("$configDir/checkstyle/k12_checkstyle.xml")
configProperties.checkstyleSuppressionsPath = file("$configDir/checkstyle/suppressions.xml").absolutePath
source 'src'
include '**/*.java'
exclude '**/gen/**'
exclude 'androidTest/**'
exclude 'test/**'
ignoreFailures true
classpath = files()
}
五、插件的接入與使用
檢測范圍
lint、PMD、findBugs和CheckStyle檢測范圍之和。
插件安裝
- 下載整合插件的文件包,和app工程目錄同級放置。
- 在app的build.gradle文件導入整合插件腳本
apply from: '../config/quality.gradle'
插件使用
- 修改 quality.gradle 的appDir字段,設置檢測的工程目錄
// 應用目錄名稱
def appDir = "app-k12"
- 進入工程根目錄,運行 gradle check ,檢測完成后,會在 build/reports 下生成相應的檢測報告文件。當然也可以按照每個插件的使用方式單獨使用。
來自:http://www.jianshu.com/p/2b8d34b2267c