Error-prone,Google出品的Java和Android Bug分析利器

vsgdk5557 7年前發布 | 7K 次閱讀 Java 安卓開發 Android開發 移動開發

是什么

  • 靜態的Java和Android bug分析利器
  • 由Google出品
  • 由error-prone接管compiler,在代碼編譯時進行檢查,并拋出錯誤中斷執行
  • 在拋出錯誤的同時給出具體的原因和相應方案
  • error-prone github 地址為 https://github.com/google/error-prone

舉幾個例子

private void testCollectionIncompatibleType() {
    Set<Short> set = new HashSet<>();
    set.add(Short.valueOf("1"));
    set.remove(0);
}

上面的代碼中

  • set是一個接受Short類型的集合
  • 我們想通過類似從List.remove(index)方式刪除一個元素
  • 但是Set沒有remove(index)方法,有的只是remove(Object)方法,普通編譯器不會報錯,而error-prone則會發現

報出的錯誤信息為

/Users/jishuxiaoheiwu/github/ErrorProneSample/app/src/main/java/com/example/jishuxiaoheiwu/errorpronesample/MainActivity.java:24:
error: [CollectionIncompatibleType] Argument '0' should not be passed to this method; its type int is not compatible with its collection's type argument Short
        set.remove(0);
                  ^
    (see http://errorprone.info/bugpattern/CollectionIncompatibleType)

再舉一個例子

"hello World".getBytes().toString();

報出的錯誤是

/Users/jishuxiaoheiwu/github/ErrorProneSample/app/src/main/java/com/example/jishuxiaoheiwu/errorpronesample/MainActivity.java:16:
error: [ArrayToString] Calling toString on an array does not provide useful information
        "hello World".getBytes().toString();
                                         ^
    (see http://errorprone.info/bugpattern/ArrayToString)

提示上面的byte[].toString()方法打印沒有有用信息。

BugPattern

Error-prone是基于BugPattern來發現問題的,覆蓋范圍不僅限于Java還包含Android代碼。一些比較常見的BugPattern有如下這些

  • ArrayToString 直接調用數組的toString方法打印不出有用信息
  • DivZero 0不能做除數,即分母
  • DefaultCharset 調用系統默認的Charset
  • MissingDefault switch中缺少default
  • MislabeledAndroidString Android中的字符串命名和內容不匹配,具有誤導性
  • HardCodedSdCardPath 硬編碼sd卡路徑
  • IsLoggableTagLength log tag字符數量過長
  • 其他
  • 更多的bug pattern請參考 bugpatterns

BugPattern有三種嚴重程度,如下

  • ERROR
  • WARNING
  • SUGGESTION

只有ERROR的嚴重程度才會中斷當前的編譯,其他情況都會以日志輸出形式展現。

如何配置

error-prone有對應的gradle插件,只需要應用即可。需要的操作很簡單,只需要三步

  • 增加相應的maven repo
  • 在依賴中設置error-prone plugin classpath
  • 應用error-prone plugin

一個完整的代碼示例如下,修改的文件為Project的build.gradle文件

buildscript {
    repositories {
        jcenter()
        // error-prone相關配置
        maven {
            url "

allprojects { repositories { jcenter() } //error-prone相關配置 apply plugin: "net.ltgt.errorprone" } </code></pre>

開啟/關閉部分檢查

Error-prone plugin提供了方法允許我們配置bugpattern的處理方式。

基本的做法是

tasks.withType(JavaCompile) {
  options.compilerArgs += [ '-Xep:<checkName>[:severity]' ]
}

比如我們想要將ArrayToString從ERROR轉成WARNING,我們可以這樣做

tasks.withType(JavaCompile) {
    options.compilerArgs += [ '-Xep:ArrayToString:WARN' ]
}

除此之外還有一些特殊的參數

  • -XepAllErrorsAsWarnings 將全部的Error轉成WARNING
  • -XepAllDisabledChecksAsWarnings 開啟全部的check,之前禁止的作為WARNING級別處理
  • -XepDisableAllChecks 關閉所有的check

分條件開啟error-prone插件

理論上,error-prone在編譯時期進行代碼分析并檢查,會延長了編譯時間,加之Gradle編譯本來就很慢,為了不對我們日常的構建造成影響,我們可以分條件開啟error-prone,即

  • 在日常開發構建,禁止應用error-prone插件,不對構建時間影響
  • 在特殊場景,比如持續集成時應用error-prone插件,用來發現問題。

具體的做法是通過想gradle傳遞參數來實現。簡易代碼如下。

allprojects {
    repositories {
        jcenter()
    }
    //如果接受的參數有enableErrorProne則應用插件,否則不應用
    if (project.hasProperty("enableErrorProne")) {
        apply plugin: "net.ltgt.errorprone"
    }
}

使用如下,則會開啟應用插件

./gradlew assembleDebug -PenableErrorProne

注意

  • 由于是靜態分析工具,即使問題代碼不被執行也會檢測出來。
  • 一次編譯過程中,error-prone可以報出多個錯誤
  • Android Studio也有對應的error-prone插件,大家也可以使用。

以上就是關于error-prone的一些簡單總結。Error-prone在Flipboard中已經應用很久,采用的方式為開發構建時不開啟,在持續集成時開啟。大家可根據自己和團隊的需要選擇并應用error-prone,來快速發現問題并改善代碼的質量。

 

來自:http://droidyue.com/blog/2017/04/09/error-prone-tool-for-java-and-android/

 

 本文由用戶 vsgdk5557 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!