在Android自動化測試技術中,我們首先會運用各種代碼檢查工具對Android代碼進行檢查,從而提前發(fā)現代碼中存在的一些bug和隱患,提高代碼質量录语。FindBug就是Android代碼檢查最常用的工具之一。
FindBug
是一款開源的 Java
代碼檢查工具,遵循 GNU
公共許可協(xié)議。它可以檢查 Java
類或者 JAR
文件,運行的是 Java
字節(jié)碼而不是源碼,檢查原理是:將字節(jié)碼與一組缺陷模式進行對比來發(fā)現可能存在的問題,這些問題包括空指針引用购公、無限遞歸循環(huán)蕴侣、死鎖等。檢查的 bug
類型包括:
- Malicious code vulnerability:惡意代碼
- Dodgy code:不符合規(guī)范的代碼
- Internationalization:國際化相關問題滞项,如錯誤的字符串轉換;
- Bad practice:壞的實踐:常見代碼錯誤,序列化錯誤,用于靜態(tài)代碼檢查時進行缺陷模式匹配;
- Multithreaded correctness:多線程的正確性:如多線程編程時常見的同步,線程調度問題;
- Performance:運行時性能問題狭归,如由變量定義,方法調用導致的代碼低效問題。
- Correctness:可能導致錯誤的代碼,如空指針引用等;
- Experimental:可能受到的惡意攻擊,如訪問權限修飾符的定義等;
- Security:安全性
這里最后一個我在檢查項目的時候沒有看到文判,不知道是否真的存在过椎。
在AndroidStudio上安裝FindBugs
Android Studio
提供在線和離線兩種安裝插件的方式。
在線安裝FindBugs:
首先打開 Android Studio
的設置中的插件戏仓,輸入 FindBugs
疚宇,如下圖所示亡鼠,點擊 Browse
查找,選擇 FindBugs-IDEA
然后單擊右側的 Install plugin
按鈕進行安裝(因為這里已經安裝了 FindBugs
所以右側沒有 Install plugin
按鈕)。如下圖:
按步驟來(我感覺這是最詳細的敷待,歡迎來辯间涵,哈哈哈)。
離線安裝FindBugs:
首先榜揖,下載用于 IntelliJ IDEA
環(huán)環(huán)境下的 FindBugs
安裝包(下載地址:FindBugs download | SourceForge.net)勾哩。其次,打開Android Studio
的設置中的插件举哟,點擊上圖 標注3
按鈕的右邊按鈕:Install plugin from disk
思劳,選擇剛才下載的 FindBugs
安裝包進行安裝即可。
FindBugs的基本使用
FindBugs
安裝完成之后需要重啟 Android Studio
妨猩,重啟之后會看到 FindBugs
的界面窗口潜叛,如下圖:
現在說一下,圖上標注的含義:
檢查范圍
- 標注1:檢查當前類(只有在選中類的時候可點擊)壶硅。
- 標注2:檢查當前包威兜。
- 標注3:檢查當前模塊。
- 標注4:檢查當前項目庐椒。
- 標注5:自定義設置檢查范圍椒舵。
結果查看方式
- 標注6:按照bug類型查看。
- 標注7:按照類查看约谈。
- 標注8:按照包結構查看逮栅。
- 標注9:按照bug等級查看。
好了窗宇,還是那句話措伐,開始改吧,加油军俊!
錯誤詳情
先來看一張圖:
priority
代表了嚴重等級,紅色最嚴重粪躬,所以我們可以重點關注一下紅色担败。下方是錯誤詳情:
1. Bad practice 壞的實踐
一些不好的實踐,下面列舉幾個:
1)類定義了equals()镰官,卻沒有hashCode()提前;。
2)Statement 的execute方法調用了非常量的字符串泳唠;或Prepared Statement是由一個非常量的字符串產生狈网。
3)方法終止或不處理異常,一般情況下,異常應該被處理或報告拓哺,或被方法拋出勇垛。
2. Correctness 一般的正確性問題
可能導致錯誤的代碼,下面列舉幾個:
1)空指針被引用;在方法的異常路徑里,空指針被引用耘婚;方法沒有檢查參數是否null;null值產生并被引用讼积;null值產生并在方法的異常路徑被引用;傳給方法一個聲明為@NonNull的null參數脚仔;方法的返回值聲明為@NonNull實際是null币砂。
2)類定義了hashcode()方法,但實際上并未覆蓋父類Object的hashCode()玻侥;類定義了tostring()方法,但實際上并未覆蓋父類Object的toString()亿蒸;很明顯的方法和構造器混淆凑兰;方法名容易混淆。
3)方法嘗試訪問一個Prepared Statement的0索引边锁;方法嘗試訪問一個ResultSet的0索引姑食。
4)所有的write都把屬性置成null,這樣所有的讀取都是null茅坛,這樣這個屬性是否有必要存在音半;或屬性從沒有被write。
3. Internationalization 國際化
當對字符串使用upper或lowercase方法贡蓖,如果是國際的字符串曹鸠,可能會不恰當的轉換。
4. Malicious code vulnerability 惡意代碼
如果代碼公開斥铺,可能受到惡意攻擊的代碼彻桃,下面列舉幾個:
1)一個類的finalize()應該是protected,而不是public的晾蜘。
2)屬性是可變的數組邻眷;屬性是可變的Hashtable;屬性應該是package protected的剔交。
5. Multithreaded correctness 多線程的正確性
多線程編程時肆饶,可能導致錯誤的代碼,下面列舉幾個:
1)ESync:空的同步塊岖常,很難被正確使用驯镊。
2)MWN:錯誤使用notify(),可能導致IllegalMonitorStateException異常;或錯誤的
使用wait()阿宅。
3)使用notify()而不是notifyAll()候衍,只是喚醒一個線程而不是所有等待的線程。
4)構造器調用了Thread.start()洒放,當該類被繼承可能會導致錯誤蛉鹿。
6. Performance 性能問題
可能導致性能不佳的代碼,下面列舉幾個:
1)DM:方法調用了低效的Boolean的構造器往湿,而應該用Boolean.valueOf(…)妖异;用類似
Integer.toString(1) 代替new Integer(1).toString();方法調用了低效的float的構造器领追,應該用靜態(tài)的valueOf方法他膳。
2)SIC:如果一個內部類想在更廣泛的地方被引用,它應該聲明為static绒窑。
3)SS: 如果一個實例屬性不被讀取棕孙,考慮聲明為static。
4)UrF:如果一個屬性從沒有被read些膨,考慮從類中去掉蟀俊。
5)UuF:如果一個屬性從沒有被使用,考慮從類中去掉订雾。
7. Dodgy 不符合規(guī)范的肢预,有潛在危險的
具有潛在危險的代碼,可能運行期產生錯誤洼哎,下面列舉幾個:
1)CI: 類聲明為final但聲明了protected的屬性烫映。
2)DLS:對一個本地變量賦值,但卻沒有讀取該本地變量噩峦;本地變量賦值成null锭沟,卻沒有讀取該本地變量。
3)ICAST: 整型數字相乘結果轉化為長整型數字识补,應該將整型先轉化為長整型數字再相乘冈钦。
4)INT:沒必要的整型數字比較,如X <= Integer.MAX_VALUE李请。
5)NP: 對readline()的直接引用瞧筛,而沒有判斷是否null;對方法調用的直接引用导盅,而方法可能返回null较幌。
6)REC:直接捕獲Exception,而實際上可能是RuntimeException白翻。
7)ST: 從實例方法里直接修改類變量乍炉,即static屬性绢片。
最后,參考鏈接:
輕松幫你發(fā)現Bug(FindBugs在AndroidStudio上的應用)
findbugs 性能優(yōu)化總結