前言
一個良好的代碼規(guī)范吟宦,能夠在項目當(dāng)中發(fā)揮舉足輕重的作用;它不僅能使我們的開發(fā)更加高效涩维,而且還會減少BUG產(chǎn)生的幾率殃姓,增強代碼可維護性及穩(wěn)定性。
JAVA代碼規(guī)范
強制性規(guī)范:
- 代碼中的命名均不能以下劃線或美元符號
開始
瓦阐,也不能以下劃線或美元符號結(jié)束
蜗侈。 - 代碼中的命名嚴(yán)禁使用拼音與英文混合的方式,更不允許直接使用中文的方式睡蟋。
- 類名使用UpperCamelCase 風(fēng)格踏幻,必須遵從駝峰形式。
- 方法名戳杀、參數(shù)名该面、成員變量夭苗、局部變量都統(tǒng)一使用 lowerCamelCase 風(fēng)格,必須遵從駝峰形式吆倦。
- 常量命名全部大寫听诸,單詞間用下劃線隔開,力求語義表達完整清楚蚕泽,不要嫌名字長例如:MAX_STOCK_COUNT晌梨。
- 抽象類命名使用 Abstract 或 Base 開頭;
- 異常類命名使用 Exception 結(jié)尾;
- 測試類 命名以它要測試的類的名稱開始。
- 杜絕不規(guī)范的英文縮寫:AbstractClass 縮寫成AbsClass须妻;condition縮寫成condi;此類隨意縮寫嚴(yán)重降低了代碼的可閱讀性仔蝌。
- 如果使用到了設(shè)計模式,建議在類名中體現(xiàn)出具體的模式:
public class ComponentFactory
public class BufferStrategy
public class ScrollerProxy
- 關(guān)于Service或Dao層的命名
插入:insert(推薦)或save
刪除:delete
修改:update(推薦)或modify
查詢單個對象:get
查詢多個對象:list
- 實體類必須重載toString()方法荒吏,這樣可以通過調(diào)用對象的toString()來排查問題敛惊。
- Object 的 equals 方法容易拋空指針異常,應(yīng)使用常量或確定有值的對象來調(diào)用 equals绰更。
正例: "test".equals(object);
反例: object.equals("test");
- 避免通過一個類的對象引用訪問此類的靜態(tài)變量或靜態(tài)方法瞧挤,無謂增加編譯器解析成本,直接用類名來訪問即可儡湾。
推薦規(guī)范:
- 集合初始化時特恬,盡量指定集合初始值大小徐钠;
ArrayList盡量使用ArrayList(int initialCapacity) 初始化 癌刽。
- 使用 entrySet 遍歷 Map 類集合 KV,而不是 keySet 方式進行遍歷
說明:keySet 其實是遍歷了 2 次尝丐,一次是轉(zhuǎn)為 Iterator 對象显拜,另一次是從 hashMap 中取出 key 所對應(yīng)的 value。而 entrySet 只是遍歷了一次就把 key 和 value 都放到了 entry 中爹袁,效 率更高远荠。如果是 JDK8,使用 Map.foreach 方法失息。
- 高度注意 Map 類集合 K/V 能不能存儲 null 值的情況矮台,如下表格:
集合類 | Key | Value | Super | 說明 |
---|---|---|---|---|
Hashtable | 不允許為null | 不允許為null | Dictionary | 線程安全 |
ConcurrentHashMap | 不允許為null | 不允許為null | AbstractMap | 分段鎖技術(shù) |
TreeMap | 不允許為null | 允許為null | AbstractMap | 線程不安全 |
HashMap | 允許為null | 允許為null | AbstractMap | 線程不安全 |
- 利用 Set 元素唯一的特性,可以快速對一個集合進行去重操作根时,避免使用 List 的 contains 方法進行遍歷瘦赫、對比、去重操作蛤迎。
- 通過雙重檢查鎖(double-checked locking)(在并發(fā)場景)實現(xiàn)延遲初始化的優(yōu) 化問題隱患(可參考 The "Double-Checked Locking is Broken" Declaration),推薦問題 解決方案中較為簡單一種(適用于 JDK5 及以上版本)确虱,將目標(biāo)屬性聲明為 volatile 型。
*反例*:
class Foo {
private Helper helper = null;
public Helper getHelper() {
if (helper == null)
synchronized(this) {
if (helper == null)
helper = new Helper();
}
return helper;
}
// other functions and members...
}
Android代碼規(guī)范
代碼:
- Activity 命名一律使用 模塊名+Activity 的方式替裆。例如校辩,LoginActivity窘问、SignupActivity;
- Fragment 命名一律使用 模塊名+Fragment 的方式宜咒;
- 自定義View:Custom(建議)+功能名+View/ViewGroup(具體的組件名稱)惠赫。例如:CustomImageScroller、CustomRatingBar故黑。
- Widget 小組件:ScanWidget儿咱、WeatherWidget。
- Dialog對話框:功能名+Dialog场晶。例如:LoginDialog混埠、ProgressDialog
- 盡量在每一個Activity或類中加入TAG,方便我們查看Activity的信息,這里Android Studio提供了快捷方式logt方式即可快速生成當(dāng)前類的常量诗轻。
- 對于使用Intent傳遞數(shù)據(jù)钳宪,聲明一些Key的時候:
EXTRA_KEY_+具體Key名稱,例如我們現(xiàn)在有一個人的名字和年齡要傳那么首先定義:
public static final String EXTRA_KEY_PERSON_NAME="EXTRA_KEY_PERSON_NAME"
public static final String EXTRA_KEY_PERSON_NAME="EXTRA_KEY_PERSON_AGE"
然后在具體的頁面 new Intent()扳炬,依次傳遞進去值吏颖,這樣寫其實沒什么問題;但是試想一下恨樟,如果你要調(diào)用的Activity是類似于一個工具性質(zhì)或通用的Activity(圖片選擇器半醉、登錄、注冊等等)厌杜,這時候你要傳遞的key又很多,如果業(yè)務(wù)復(fù)雜的話计螺,你應(yīng)該會被這樣冗余且不易閱讀的代碼直接搞崩潰掉夯尽。
所以最好的辦法就是在你要調(diào)用Activity提供一個靜態(tài)工廠方法,要知道靜態(tài)工廠方法所帶來的好處太多了登馒,由于Activity是不允許通過new的方式來初始化的匙握,所以靜態(tài)工廠方法的好處在此就不那么明顯,但是已經(jīng)足夠我們優(yōu)化我們的代碼了陈轿。舉個例子圈纺,我們有一個筆記 NoteActivity,用于創(chuàng)建筆記和修改筆記麦射,
//筆記Id
private static final String EXTRA_KEY_NOTE_ID ="EXTRA_KEY_NOTE_ID" ;
//筆記內(nèi)容
private static final String EXTRA_KEY_NOTE_CONTENT ="EXTRA_KEY_NOTE_CONTENT" ;
//筆記模式
private static final String EXTRA_KEY_NOTE_MODE ="EXTRA_KEY_NOTE_MODE" ;
//用于創(chuàng)建筆記
public static void startForCreate(Context context, int noteId) {
start(context, noteId, null, MODE_CREATE);
}
//用于編輯筆記
public static void startForEdit(Context context, int noteId, String content) {
start(context, noteId, content, MODE_UPDATE);
}
public static void start(Context context, int noteId, String content, int mode) {
Intent starter = new Intent(context, TableShareListSettingActivity.class);
starter.putExtra(EXTRA_KEY_NOTE_ID,noteId);
starter.putExtra(EXTRA_KEY_NOTE_CONTENT,content);
starter.putExtra(EXTRA_KEY_NOTE_CONTENT,mode);
context.startActivity(starter);
}
通過以上方法蛾娶,我們能夠很好的解耦復(fù)雜的Activity之間的調(diào)用,再加上靜態(tài)方法工廠方法名潜秋,代碼可閱讀行大大提高蛔琅,最終我們看到的調(diào)用NoteActivity將會是很簡潔的一段代碼:
NoteActivity.startForCreate(this,noteId);
NoteActivity.startForEdit(this,noteId,content);
此外,Android Studio工具中其實已經(jīng)在Live Template中提供了這樣的代碼:CMD+J( For MAC OS),簡單的輸入starter就可以快速地在當(dāng)前的Activity中添加一個Intent的靜態(tài)操作方法峻呛,這其實也說明了Android官方團隊也鼓勵我們這么做罗售。
如下圖所示:
一下子省了好多代碼辜窑,簡直太贊了有木有!
- 增加類注釋寨躁,使用Android Studio的 File And Code Template:
- 所有的常量加上注釋穆碎,且功能相同的排放在一起,不同的進行換行职恳;
- Activity中變量采用m開頭+類名所禀。例如,mTable话肖、mPerson北秽;
- Activity中的控件:m+模塊名+控件類型名稱。例如最筒,mLoginEditText,mLoginTextView;
資源Res
1.按照資源的類型贺氓,分為以下幾種
控件Id命名:控件縮寫 _模塊(module) _功能名(function)
控件類型 | ID命名規(guī)則 |
---|---|
TextView | tv_module_function |
EditText | et_module_function |
ImageView | iv_module_function |
Button | btn_module_function |
ListView | lv_module_function |
GridView | gv_module_function |
CheckBox | check_module_function |
RadioButton | radio_module_function |
LinearLayout | ll_module_function |
RelativeLayout | rl_module_function |
FrameLayout | fl_module_function |
GridLayout | gl_module_function |
··· | ··· |
Color資源命名
Resources Type | 命名規(guī)則 |
---|---|
color | 組件名+具體作用名。例 R.color.button_text |
String資源命名
Resources Type | 命名規(guī)則 |
---|---|
string | 具體功能床蜘。 例 R.string.hello |
Drawable資源命名
Resources Type | 命名規(guī)則 |
---|---|
launcher icon | ic_launcher辙培。例R.drawable.ic_launcher |
normal icon | ic_具體模塊_功能。例R.drawable.ic_audio_pause |
Toolbar icon | ic_ab_功能名邢锯。例如ic_ab_search |
selector | selector_模塊_功能名扬蕊。例如 selector_login_button |
shape | shape_模塊功能名狀態(tài)。例如 R.drawable.shape_login_button_pressed ,R.drawable.shape_login_button_normal |
Layout資源命名
類型 | 命名規(guī)則 |
---|---|
activity | activity_模塊名丹擎。例如 R.layout.activity_login |
fragment | fragment_模塊名尾抑。例如 R.layout.fragment_login_layout_header |
include | layout_模塊名_功能名。例如 @layout/layout_login_bottom |
adapter | adapter_item_模塊名_功能名蒂培。例如 R.layout.adapter_item_simple_text |
dialog | dialog_模塊_功能名再愈。例如 R.layout.dialog_time_picker |
list header | header_模塊_功能。例如 R.layout.header_main_top_ad |
list footer | footer_模塊_功能护戳。例如 R.layout.footer_main_bottom_action |
widget | widget_模塊_功能翎冲。例如 R.layout.widget_app_clock |
··· | ··· |
Menu資源命名
Resources Type | 命名規(guī)則 |
---|---|
menu | menu_模塊名。例如 menu_login |
Values資源命名
Resources Type | 命名規(guī)則 |
---|---|
color | 模塊名_color媳荒。例如 material_design_color |
dimens | 模塊名_dimens抗悍。例如 material_design_dimens |
style | 模塊名_style。例如 material_design_style |
themes | 模塊名_themes钳枕。例如 material_design_themes |
附錄
UI控件縮寫表
控件 | 縮寫 | 例子 |
---|---|---|
LinearLayout | ll | llFriend或者mFriendLL |
RelativeLayout | rl | rlMessage或mMessageRL |
FrameLayout | fl | flCart或mCartFL |
TableLayout | tl | tlTab或mTabTL |
Button | btn | btnHome或mHomeBtn |
ImageButton | ibtn | btnPlay或mPlayIBtn |
TextView | tv | tvName或mNameTV |
EditText | et | etName或mNameET |
ListView | lv | lvCart或mCartLV |
ImageView | iv | ivHead或mHeadIV |
GridView | gv | gvPhoto或mPhotoGV |
常見的英文單詞縮寫
名稱 | 縮寫 |
---|---|
icon | ic (主要用在app的圖標(biāo)) |
color | cl(主要用于顏色值) |
divider | di(主要用于分隔線缴渊,不僅包括Listview中的divider,還包括普通布局中的線) |
selector | sl(主要用于某一view多種狀態(tài)鱼炒,不僅包括Listview中的selector疟暖,還包括按鈕的selector) |
average | avg |
background | bg(主要用于布局和子布局的背景) |
buffer | buf |
control | ctrl |
delete | del |
document | doc |
error | err |
escape | esc |
increment | inc |
infomation | info |
initial | init |
image | img |
Internationalization | I18N |
length | len |
library | lib |
message | msg |
password | pwd |
position | pos |
server | srv |
string | str |
temp | tmp |
window | wnd(win) |
參考資料
一些插件
ADB Idea
adb常用命令,ctrl+shift+a輸入adb可調(diào)用
Android Methods Count
引用庫方法數(shù)統(tǒng)計
Exynap
快速使用代碼模板,ctrl+shift+d調(diào)用
ADB WIFI
無需root就能wifi調(diào)試
CodeGlance
最大的用途:可用于快速定位代碼
Lifecycle-Sorter
可以根據(jù)Activity或者fragment的生命周期對其生命周期方法位置進行先后排序俐巴, 快捷鍵Ctrl + alt + K
folding-plugin
可以給資源文件分組骨望,并且不移動文件,也不會創(chuàng)建文件夾:Android File Grouping Plugin
strings-xml-tools
管理Android工程中字符串國際化的插件
.ignore:
.gitignore配置插件欣舵。
AndroidLocalizationer
可用于將項目中的 string 資源自動翻譯為其他語言的 Android Studio/IntelliJ IDEA 插件
Alibaba Coding Guidelines