Android編碼規范
================
[TOC]
## 介紹
### 1. 為什么需要編碼規范?
--------------
編碼規范對于程序員而言尤為重要,有以下幾個原因:
- 一個軟件的生命周期中,80%的花費在于維護
- 幾乎沒有任何一個軟件,在其整個生命周期中,均由最初的開發人員來維護
- 編碼規范可以改善軟件的可讀性,可以讓程序員盡快而徹底地理解新的代碼
## 書寫規范
### 1. 編碼格式
* * * * *
文件編碼格式統一用UTF-8
### 2. Tab縮進
* * * * *
Tab縮進統一為4個空格。將Tab size設置為4,切換到不同tab長度的環境時還能繼續保持統一的縮進樣式。
### 3. 花括號
* * * * *
花括號不要單獨一行,和它前面的代碼同一行。而且,花括號與前面的代碼之間用一個空格隔開。
~~~
public void method() { // Good
}
public void method()
{ // Bad
}
public void method(){ // Bad
}
~~~
### 4. 空格
* * * * *
if、else、for、switch、while等邏輯關鍵字與后面的語句留一個空格隔開。
~~~
// Good
if (booleanVariable) {
// TODO while booleanVariable is true
} else {
// TODO else
}
// Bad
if(booleanVariable) {
// TODO while booleanVariable is true
}else {
// TODO else
}
~~~
運算符兩邊各用一個空格隔開。
~~~
int result = a + b; //Good
int result=a+b; //Bad
~~~
方法的每個參數之間用一個空格隔開。
~~~
public void method(String param1, String param2); // Good
method(param1, param2); // Good
method(param1,param2); // Bad
~~~
類和方法花括號前面用一個空格隔開。
~~~
public class LoginActivity {//Good
private void getData() {//Good
//do something
}
}
public class LoginActivity{//Bad
private void getData(){//Bad
//do something
}
}
~~~
### 5. 空行
* * * * *
將邏輯相關的代碼段用空行隔開,以提高可讀性。空行也只空一行,不要空多行。在以下情況需用一個空行:
- 兩個方法之間
- 方法內的兩個邏輯段之間
- 方法內的局部變量和方法的第一條邏輯語句之間
- 常量和變量之間
### 6. 表達式換行
* * * * *
當一個表達式無法容納在一行內時,可換行顯示,另起的新行用8個空格縮進。
~~~
public void someMethod(longExpression1, longExpression2,
longExpression3, longExpression4, longExpression5);
~~~
### 7. 聲明變量
* * * * *
一行聲明一個變量,不要一行聲明多個變量,這樣有利于寫注釋。
~~~
private String param1; // 參數1
private String param2; // 參數2
~~~
### 8. 行寬
* * * * *
行寬設置為100,設置格式化時自動斷行到行寬位置。
### 9. 方法行數
* * * * *
一個方法最多不要超過40行代碼,如果方法太長,說明當前方法業務邏輯已經非常復雜,那么就需要進行方法拆分,保證每個方法只作一件事。
### 10. 使用快捷鍵進行代碼自動格式化
* * * * *
Mac Eclipse:command + shift + f
### 11. 單位
* * * * *
文字大小的單位統一用sp,控件大小的單位統一用dp
### 12. 資源文件
* * * * *
- 字符串統一在string.xml中定義
- 顏色值統一在color.xml中定義,不要使用系統的顏色
- 尺寸值統一在dimens.xml中定義
## 命名規范
### 1. 包命名
* * * * *
命名規則:一個唯一包名的前綴總是全部小寫的ASCII 字母并且是一個頂級域名,通常是com,edu,gov,mil,net,org。包名的后續部分根據不同機構各自內部的命名規范而不盡相同。這類命名規范可能以特定目錄名的組成來區分部門 (department) ,項目(project),機器(machine),或注冊名(login names)。
規約:**沒有特別要求**的情況下,包名命名規則為:
**域名.公司名稱(縮寫).項目名稱(縮寫).模塊名稱**
*例如: 公司名稱是xizi,項目名稱是xzmpo,存放Activity模塊的包名為:**com.xizi.xzmpo.activity***
項目中各模塊包名:
**com.xizi.xzmpo.activity** 放所有Activity
**com.xizi.xzmpo.adapter** 放所有Adapter
**com.xizi.xzmpo.app** 放Application
**com.xizi.xzmpo.db** 放數據庫
**com.xizi.xzmpo.entity** 放實體
**com.xizi.xzmpo.fragment** 放Fragment
**com.xizi.xzmpo.service** 放服務
**com.xizi.xzmpo.util** 放工具
**com.xizi.xzmpo.widget** 放控件
**com.xizi.xzmpo.constant** 放常量
### 2. 類和接口命名
* * * * *
命名規則:類名是一個**名詞**,采用大小寫混合的方式,每個單詞的首字母大寫。盡量使你的類名簡潔而富于描述。使用完整單詞,避免縮寫詞(除非該縮寫詞被更廣泛使用,像 URL,HTML)。
規約:類名必須使用駝峰規則,即首字母必須大寫,如果為詞組,則每個單詞的首字母也必須要大寫,類名必須使用名詞,或名詞詞組。要求類名簡單,不允許出現無意義的單詞(*如 class XXXActivity*)。
*如:class AboutActivity 正確*
*如:class AddBookReadPlanActivity 錯誤! 應為 class BookReadPlanAddActivity*
*(BookReadPlan---名詞)+(add---動詞)=名詞*
*(add---動詞)+ (BookReadPlan---名詞)=動詞*
以下為幾種常用類的命名:
**activity類,命名以Activity為后綴,如:LoginActivity**
**fragment類,命名以Fragment為后綴,如:CollectFragment**
**service類,命名以Service為后綴,如:DownloadService**
**adapter類,命名以Adapter為后綴,如:CouponListAdapter**
**工具類,命名以Util為后綴,如:EncryptUtil**
**接口一般要使用able、ible、er 等后綴,如: JPushReceiver**
### 3. 方法命名
* * * * *
命名規則:方法名是一個動詞,采用大小寫混合的方式,第一個單詞的首字母小寫,其后單詞的首字母大寫。
*例如: public void run(); public String getBookName();*
類中常用方法的命名:
1. 類的獲取方法(一般具有返回值)一般要求在被訪問的字段名前加上get,*如*
*getFirstName(),getLastName()*。一般來說,get前綴方法返回的是單個值,find前綴的方法返回的是列表值。
2. 類的設置方法(一般返回類型為void):被訪問字段名的前面加上前綴 set,*如*
*setFirstName(),setLastName()*.
3. 類的布爾型的判斷方法一般要求方法名使用單詞 is或has 做前綴,*如isPersistent(),isString()*。或者使用具有邏輯意義的單詞,*例如equal 或equals*。
4. 類的普通方法一般采用完整的英文描述說明成員方法功能,第一個單詞盡可能采用動詞,首字母小寫,*如openFile(), addCount(), initView(), loadData()*。
5. 構造方法應該用遞增的方式寫。(參數多的寫在后面)。
### 4. 變量命名
* * * * *
命名規則:第一個單詞的首字母小寫,其后單詞的首字母大寫。變量名不應以下劃線或美元符號開頭,盡管這在語法上是允許的。變量名應簡短且富于描述。變量名的選用應該易于記憶,即,能夠指出其用途。盡量避免單個字符的變量名,除非是一次性的臨時變量。
*例如:String bookName;*
規約:變量命名也必須使用駝峰規則,但是首字母必須小寫,變量名盡可能的使用名詞或名詞詞組。同樣要求簡單易懂,不允許出現無意義的單詞。
*如:String bookName; 正確*
*如:String bookNameString; 錯誤!*
### 5. 常量命名
* * * * *
命名規則:類常量的聲明,應該全部大寫,單詞間用下劃線隔開。
*例如:static final int MIN_WIDTH = 4;*
*例如:static final int MAX_WIDTH = 999;*
*例如:static final int GET_THE_CPU = 1;*
### 6. 異常命名
* * * * *
自定義異常的命名必須以Exception為結尾。
### 7. layout命名
* * * * *
規約:layout xml 的命名必須以 全部單詞小寫,單詞間以下劃線分割,并且使用名詞或名詞詞組。命名規則為:**組件類型\_{范圍\_}功能**,范圍可選,只在有明確定義的范圍內才需要加上。
以下為幾種常用的組件類型命名:
activity\_{范圍\_}功能,為Activity的命名格式
fragment\_{范圍\_}功能,為Fragment的命名格式
dialog\_{范圍\_}功能,為Dialog的命名格式
item\_list\_{范圍\_}功能,為ListView的item命名格式
item\_grid\_{范圍\_}功能,為GridView的item命名格式
header\_list\_{范圍\_}功能,為ListView的HeaderView命名格式
footer\_list\_{范圍\_}功能,為ListView的FooterView命名格式
### 8. 控件id命名
* * * * *
規約:layout 中所使用的id必須以全部單詞小寫,單詞間以下劃線分割,并且使用名詞或名詞詞組,并且要求能夠通過id直接理解當前組件要實現的功能。命名規則為:**控件縮寫\_{范圍\_}意義**,范圍可選,只在有明確定義的范圍內才需要加上。
*如:某TextView @+id/txtbookname 錯誤 !應為 @+id/txt_book_name*
*如:某EditText @+id/edtbookname 錯誤 !應為 @+id/edt_book_name*
**控件縮寫**
| 控件 | 縮寫 | 控件 | 縮寫 |
| -- | -- | -- | -- |
| TextView | txt | EditText | edt |
| Button | btn | ImageButton | ibtn |
| ImageView | img | ListView | list |
| RadioGroup | group | RadioButton | rbtn |
| ProgressBar | progress | SeekBar | seek |
| CheckBox | chk | Spinner | spinner |
| TableLayout | table | TableRow | row |
| LinearLayout | llayout | RelativeLayout | rlayout |
| ScrollView | scroll | SearchView | search |
| TabHost | host | TabWidget | widget |
### 9. strings命名
* * * * *
命名規則為: **類型\_{范圍\_}功能**,范圍可選。
以下為幾種常用的命名:
* 頁面標題,命名格式為:title_頁面
* 按鈕文字,命名格式為:btn_按鈕事件
* 標簽文字,命名格式為:label_標簽文字
* 選項卡文字,命名格式為:tab_選項卡文字
* 消息框文字,命名格式為:toast_消息
* 編輯框的提示文字,命名格式為:hint_提示信息
* 圖片的描述文字,命名格式為:desc_圖片文字
* 對話框的文字,命名格式為:dialog_文字
### 10. colors命名
* * * * *
命名規則為: **以RGB顏色值命名**。
*如:#000000命名為000000, #797979命名為797979*
### 11. drawable命名
* * * * *
命名規則為: **前綴{\_控件}{\_范圍}{\_后綴}**,控件、范圍、后綴可選,但控件和范圍至少要有一個。
* 圖標類,添加ic前綴
* 背景類,添加bg前綴
* 分隔類,添加div前綴
* 默認類,添加def前綴
* 區分狀態時,默認狀態,添加normal后綴
* 區分狀態時,按下時的狀態,添加pressed后綴
* 區分狀態時,選中時的狀態,添加selected后綴
* 區分狀態時,不可用時的狀態,添加disable后綴
* 多種狀態的,添加selector后綴(一般為ListView的selector或按鈕的selector)
### 12. 動畫文件命名
* * * * *
命名規則為: **動畫類型\_動畫方向**
* fade\_in,淡入
* fade\_out,淡出
* push\_down\_in,從下方推入
* push\_down\_out,從下方推出
* slide\_in\_from\_top,從頭部滑動進入
* zoom\_enter,變形進入
* shrink\_to\_middle,中間縮小
## 注釋規范
Java 程序有兩類注釋:實現注釋(implementation comments)和文檔注釋(document comments)。實現注釋是使用/*...*/和//界定的注釋。文檔注釋(被稱為"doc comments")由/**...*/界定。文檔注釋可以通過javadoc 工具轉換成HTML 文件。
### 1. 文件頭注釋
* * * * *
文件頂部統一添加版權聲明,聲明的內容如下:
~~~
/*
* 文件名
* 版權聲明
* 創建日期
* 版本信息,版本號
*/
~~~
注釋模板及設置方法見下面。
### 2. 類和接口注釋
* * * * *
類和接口統一添加javadoc注釋,內容如下。
~~~
/**
* 類和接口的描述信息
* 作者
* 創建日期
*/
~~~
Eclipse中設置文件頭注釋及類和接口注釋方法如下:
打開 Preference-->Java-->Code Templates-->Code-->New Java files
替換以下模板并保存即可:
~~~
/*
* @Title: ${file_name}
* @Copyright (c) ${year} 3N CTO Co.,Ltd. All rights reserved
* @data: ${date}
* @version: V1.0
*/
${filecomment}
${package_declaration}
/**
* ${todo}
* @Author ${user}
* @Date Create at ${date} ${time}
*/
${typecomment}
${type_declaration}
~~~
### 3. 方法注釋
* * * * *
下面幾種方法,都必須添加javadoc注釋,說明該方法的用途和參數說明,以及返回值的說明。其他方法也需要加上//或者/**/注釋說明。
* 接口中定義的所有方法
* 抽象類中自定義的抽象方法
* 所有類的自定義public方法和protected方法
~~~
/**
* 方法用途描述
* @param s 說明參數含義
* @return 說明返回值含義
* @throws IOException 說明發生此異常的條件
*/
~~~
Eclipse設置方法注釋模板方法如下:
打開 Preference-->Java-->Code Templates-->Comments-->Methods
替換以下模板并保存即可:
~~~
/**
* ${tags}
*/
~~~
### 4. 類成員變量和常量注釋
* * * * *
public和protected成員變量和常量需要使用javadoc形式的注釋,以說明當前變量或常量的含義;其他成員變量和常量可以添加//注釋,優先采用右側//來注釋,若注釋說明太長則在上方添加注釋。
~~~
/**現金券**/
public static final int TYPE_CASH = 1;
/**抵扣券**/
public static final int TYPE_DEBIT = 2;
/**折扣券**/
public static final int TYPE_DISCOUNT = 3;
private int id; // 券id
private String name; // 券名稱
private String introduce; // 券簡介
~~~
### 5. 其他注釋
* * * * *
方法內部的注釋 如果需要多行 使用**/*…… */**形式,如果為單行是用**//……**形式的注釋。不要在方法內部使用 javadoc 形式的注釋**“/\*\*……\*\*/”**,簡單的區分方法是,javadoc形式的注釋在 eclipse中為藍色,普通注釋為綠色。
### 6. TODO注釋
* * * * *
如果代碼是暫時的、短期的解決方案或夠用但不夠完美的使用TODO注釋:
`//TODO:Remove?this?code?after?the?UrlTable2?has?been?checked?in.`
### 7. XML注釋
* * * * *
規約:如果當前layout 或資源需要被多處調用,或為公共使用的layout(若list_item),則需要在xml寫明注釋。要求注釋清晰易懂。
## 規約
- 使用butterknife簡化代碼;
- 不要使用 try catch 處理業務邏輯!
- 代碼中不允許出現單獨的數字,字符!如果需要使用數字或字符,則將它們按照含義封裝為靜態常量!(for語句中除外)
- 判斷中如有常量,則應將常量置于判斷式的左側。
*如:if (true == isAdmin())*
- 所有if 語句必須用{}包括起來,即便是只有一句;
- 含有多種運算符的表達式中使用圓括號來避免運算符優先級問題;
- 如果一個包含二元運算符的表達式出現在三元運算符" ? : "的"?"之前,那么應該給表達式添上一對圓括號。*例如:(x >= 0) ? x : -x*
- 使用switch case 結構,如果存在非空的 case 直穿語句,主體里必須有類似 // no break 的注釋。
- versionName和versionCode在**沒有特殊要求**的情況下,使用以下規范定義:
**versionName:2.4.1 逢10進1
versionCode:24101~24199 前3位對應versionName,后面兩位是開發或者緊急升級時使用。**
*如:2.4.4 對應 24401
3.1 對應 31001
1.0 對應 10001
2.4.1緊急修復一個版本,不屬于常規升級,可以使用2.4.101 對應24101*