這次分享兩個 Android Studio 的小技巧,能夠有效提高效率和減少犯錯,尤其是在團隊協作開發中。
- Getter 模板修改--自動處理 null 判斷
- 格式化代碼自動整理方法位置--廣度 or 深度
好了,下面優先介紹下這兩個小技巧有什么作用,然后再給出使用教程,想直接看教程的可以直接跳到最后。
目的
- Getter 模板修改
開發過程中,經常會遇到空指針異常,尤其是在線上 bug 中,由於未進行 null 判斷處理導致的 bug 比例肯定不低。
另外,model 層經常需要根據服務端接口返回的數據結構進行建模,實體類中常見的有 String 類型和 List 類型的字段。而服務端的接口文檔里通常都會說明哪些字段不會為空,所以移動端建模后使用相應的實體類數據時,很少或者說會經常性忘記去做 null 判斷處理。
正常場景下,也許測不出 null 異常的問題,但如果服務器出了問題,返回了錯誤的數據,或者在某些特殊的場景下,某些字段的值偏偏就是 null,那么此時如果在使用的地方沒有進行 null 判斷處理,經常就會有問題出現,如果 app 剛好又有緩存策略,那么可能會導致特別嚴重的問題。
鑒於此,我是建議,在建模創建實體類時,如果有 String 類型和 List 類型的變量時,這些類型的 getXXX() 方法中直接進行 null 判斷處理,確保不會返回 null 值,這樣外部使用時就不用再去進行 null 判斷處理。如下:
private String mString;
private List<String> mList;
//如果String類型的字段為空,那么返回"",外部在使用getString().equal()等之類方法時如果忘記進行null判斷,也不會造成空指針異常
public String getString() {
return mString == null ? "" : mString;
}
//如果List類型字段為空,那么返回空列表。外部在使用getList().get(i)或者getList().size()等時如果忘記進行null判斷,也不會造成空指針異常
public List<String> getList() {
if (mList == null) {
return new ArrayList<>();
}
return mList;
}
這樣處理的好處是統一在實體類內部進行 null 判斷處理,外部使用的地方無需再一個個的去進行 null 判斷處理,如果外部使用時忘記進行 null 判斷處理,也不會導致空指針異常。
但,如果每次創建完實體類后都靠開發人員的主觀意識來為對應的 getXXX() 方法增加相應的 null 判斷處理代碼,很不靠譜。一切靠主觀意識來遵守的規范都不靠譜,總會由於各種原因,如任務趕,太久未接觸等等而忘記。
所以,推薦 getXXX() 方法都通過 Android Studio 來自動生成相應代碼,那么,就可以通過修改 AS 的 Getter 方法的模板文件,來達到自動生成相應的 null 判斷處理代碼,以工具代替手工,一提供效率,二強制遵守規范,三解決靠主觀意識不靠譜問題。
- 格式化代碼自動整理方法位置
當 app 經過越來越多的迭代,增加越來越多的功能時,項目難免會逐漸龐大起來,有些類里的代碼會漸漸多了起來。
為了易於閱讀,通常對類里的代碼會根據各自的職能划分到一個個方法中,盡量遵守方法的單一職責,這樣一來,各個方法之間難免會有關聯關系,a 方法調用了 b,c 方法,b 方法調用了 d 方法,等等。
這么多的方法,如果不按照一定的規范來整理、擺放的話,當類里的方法越來越多時,這些方法位置雜亂無章的擺放會給 review 人員的閱讀,或者過了很長一段時間后本人回來自己閱讀時造成一定的障礙。
常見的是規范有一種是按照權限來歸納整理,private 方法集中在一起,public 方法集中在一起。
還有一種規范是按照就近原則擺放,a 方法調用了 b 方法,那么 b 方法位置就盡量靠近 a,我個人傾向於這一種規范,這樣在熟悉一個類里的代碼時,從上往下慢慢過下來即可,不同跳過來跳過去的。
那么,同樣的問題,靠開發人員的主觀意識來遵守這種規范是很不靠譜的。寫代碼過程中,新建了一個方法時,並不會特別特意的去考慮要將它放在哪,基本就是就近放,這樣也還好,還算稍微有些關聯,有些順序。
但,如果是在后期新增功能,在舊代碼中又去新建方法時,如果對這個類不熟悉,這時候通常都不會去仔細的考慮新寫的方法應該要放在哪,要么就是放最后,要么隨手就近,久而久之,類里的方法就會越來越雜亂無章。
所以,一切靠主觀意識來遵守規范的行為都不靠譜。
鑒於此,推薦打開 Android Studio 自動整理方法位置的功能,借助工具來遵守規范,提高效率的同時也能寫出優美的代碼。
教程
Getter模板修改教程
- 隨便建個類,寫幾個屬性,然后按快捷鍵 Alt + Insert 或在代碼區域 右鍵 -> Generate -> Getter,然后會有一個彈框:
- 此時先不要點擊 OK 鍵,先點擊右上角的 … 的圖標,來修改模板文件:
- 此時只有一份 AS 默認的生成 Getter 方法的模板,要對這份模板進行修改,所以接下去可以選擇新建一份新的模板文件或者在原文件上修改都可以,比如我新建了一份 NotNull_getter 模板文件:
- 模板文件需要修改的地方就僅僅是在$(name){…} 代碼塊里的 return 生成規則,原本規則是統一返回字段值本身,根據規范新增兩條規則:增加 String 類型和 List 類型的生成規則。以下是修改后的整個模板文件代碼,可以拷貝過去直接使用:
#if($field.modifierStatic)
static ##
#end
$field.type ##
#set($name = $StringUtil.capitalizeWithJavaBeanConvention($StringUtil.sanitizeJavaIdentifier($helper.getPropertyName($field, $project))))
#if ($field.boolean && $field.primitive)
#if ($StringUtil.startsWithIgnoreCase($name, 'is'))
#set($name = $StringUtil.decapitalize($name))
#else
is##
#end
#else
get##
#end
${name}() {
#if ($field.string)
return $field.name == null ? "" : $field.name;
#else
#if ($field.list)
if ($field.name == null) {
return new ArrayList<>();
}
return $field.name;
#else
return $field.name;
#end
#end
}
- 建完新模板文件后點擊 OK 鍵,以后通過右鍵 -> Generate -> Getter 來生成 getXXX() 方法時,注意一下模板文件選擇是否正確,一般首次選擇后以后都是默認上一次的:
- 效果,getXXX() 方法都是 AS 自動生成,而且根據修改后的模板,也能保證 String 類型和 List 類型都不會返回null值。
格式化代碼自動整理方法位置教程
- 先開啟自動整理方法位置的功能,位置:
File -> Settings -> Editor -> Code Style -> Java -> Arrangement
如上圖的 2,3 點功能,默認都是關閉的。
第 2 點功能:Keep overridden methods together – keep order
意思是將由 override 標志的方法都集中放置,建議將此功能開啟,override 的方法通常要么是系統的一些回調方法,要么是我們自己定義的一些接口,這部分方法本身就有一定的關聯性,集中在一起很合理。
注意,AS支持兩種規則,一種是 keep order(按原有順序),一種是 order by name(按照方法字母表順序)。至於哪一種較合適,個人喜好,我是選擇的 keep order。
第3點功能:Keep dependent methods together
意思是將相關的方法按照某則規則放在一起,AS支持兩種規則:
breadth-first order & depth-first order
我的理解,說得通俗點也就是廣度優先和深度優先,這個功能建議開啟。
舉個例子,假設一個類里有這么幾個方法,a 調用了 b, c, d, 而 b 調用了 e, f,如果是按照廣度優先來整理這些方法的位置時,breadth-first order:
廣度優先整理后的方法順序:a, b, c, d, e, f。也就是說,方法 a 里面調用了三個方法,那么優先將這三個方法擺放在方法 a 下方,此時並不去考慮這三個方法里是否還調用了其他方法。等過完方法 a,那么以同樣的道理再去整理方法 b 中調用的方法的位置。
但如果是深度優先,那么整理后的方法順序就不同了,如下,depth-first order:
深度優先整理后的方法順序:a, b, e, f, c, d。也就是說,方法 a 內調用了三個方法,第一個方法是 b, 然后方法 b 又調用了 e, f。所以方法 b 緊接着 a 方法下面擺放,方法 e, f 緊接着方法 b 下面擺放,直到 e, f 里都沒有其他方法了。然后再重新回到方法 a 內繼續往下過方法 c 的位置,以此類推。
兩種規則有各自的好處,廣度優先側重於優先梳理每個方法的大體工作;而深度優先則側重於梳理每個方法的實現細節,流程步驟;
目前我是選擇廣度優先,因為我更側重於關注每個方法大體的工作,對於一個不熟悉的方法,大概過一下它里面的每個方法大體上做了什么,就能大概理解這個方法的大體工作。
- 以上僅僅只是開啟功能而已,而要借助 Android Studio 來自動整理方法位置,就是通過 AS 的格式化代碼功能,快捷鍵也就是 Ctrl + Alt + L 。但這個格式化操作默認是沒有啟動對方法進行整理的操作的,每次按完快捷鍵后會有如下提示:
重點在底部那行灰色的字體,通過快捷鍵 Ctrl + Alt + Shift + L 可以打開配置 dialog:
Rearrange code 默認是沒有勾選的,所以想要啟用整理方法的功能,需要將這個勾選上,以后在通過 Ctrl + Alt + L 來格式化代碼時,AS 就會根據我們在第一個步驟中設定的規則來自動整理方法的位置。
最近(2018-03)剛開通了公眾號,想激勵自己堅持寫作下去,初期主要分享原創的Android或Android-Tv方面的小知識,准備可能還有點不足,感興趣的可以先點一波關注,謝謝支持~~