參考文章:http://keeganlee.me/post/android/20150709 http://www.itdecent.cn/p/0a984f999592
https://source.android.com/source/code-style
源文件結構規(guī)范
一個源文件包含(按順序地):
- 許可證或版權信息(如有需要)
- package語句
- import語句
- 一個頂級類(只有一個)以上每個部分之間用一個空行隔開。
許可證或版權信息
如果一個文件包含許可證或版權信息,那么它應當被放在文件最前面。
package語句
package 語句不換行,列限制并不適用于package語句。(即package語句寫在一行里)
import語句
import不要使用通配符
即,不要出現(xiàn)類似這樣的import語句:import java.util.*;
不要換行
import語句不換行,列限制并不適用于import語句。(每個import語句獨立成行)
順序和間距
import語句可分為以下幾組,按照這個順序,每組由一個空行分隔:
- 導入 Android 包
- 導入第三方包(com、junit、net、org)
- java 和 javax
類聲明
只有一個頂級
類聲明每個頂級類都在一個與它同名的源文件中(當然,還包含.java后綴)。
類成員順序
類的成員順序對易學性有很大的影響,但這也不存在唯一的通用法則。不同的類對成員的排序可能是不同的。
最重要的一點,每個類應該以某種邏輯去排序它的成員,維護者應該要能解釋這種排序邏輯。比如, 新的方法不能總是習慣性地添加到類的結尾,因為這樣就是按時間順序而非某種邏輯來排序的。
區(qū)塊劃分
建議使用注釋將源文件分為明顯的區(qū)塊,區(qū)塊劃分如下
- 常量聲明區(qū)
- UI控件成員變量聲明區(qū)
- 普通成員變量聲明區(qū)
- 內部接口聲明區(qū)
- 初始化相關方法區(qū)
- 事件響應方法區(qū)
- 普通邏輯方法區(qū)
- 重載的邏輯方法區(qū)
- 發(fā)起異步任務方法區(qū)
- 異步任務回調方法區(qū)
- 生命周期回調方法區(qū)(出去onCreate()方法)
- 內部類聲明區(qū)
重載:永不分離
當一個類有多個構造函數(shù),或是多個同名方法,這些函數(shù)/方法應該按順序出現(xiàn)在一起,中間不要放進其它函數(shù)/方法。
注釋規(guī)范
文件頭注釋
文件頭注釋使用以下格式,需要將版權聲明進行替換
/**
* Copyright (C) 2017 zhangyang. All rights reserved.
*
* @Package: ${PACKAGE_NAME}
* @Description:
* @author ${USER}
* @date ${TIME}
*/
在android studio中的配置方法為:

類和接口注釋
類和接口的注釋使用以下的注釋格式:
/**
* @description $description$
* @author $user$
* @time $date$ $time$
*/
在android studio中的配置方式如下,首先選擇Editor->Live Templates,然后選擇右側的加號,選擇Template Group,命名為custom,再點擊加號,選擇Live Template,命名為cmc(cmc是快捷鍵,可以自己任意命名),然后可以對該自定義模板進行描述,并選擇應用的場景為java->Declaration,詳見下面的第二幅圖。最后注意需要點擊Edit variables,對相應的值配置由程序動態(tài)賦值,例如$user$,配置為user(),即使用當前計算機用戶名,減少工作量。



方法注釋
方法注釋采用如下格式:
/**
* @description 用戶注冊
* @author zhangyang
* @time 2017/6/19 上午9:38
* @param userName 用戶名
* @param password 密碼
* @return
*/
public int registerUser(String userName, String password);
在android studio中的配置方式與上面的類和接口的配置方式相同:
/**
* @description $description$
* @author $user$
* @time $date$ $time$
* @param $param$
* @return $return$
*/
這里我命名快捷鍵為cmf。注意:在android studio里面沒有找到自定義模板自動生成參數(shù)的方案,如果使用默認的方法生成注釋方案,則除了參數(shù)不能增加其他的自定義字段。因此需要編寫代碼時,在相應方法上輸入cmf生成注釋后,還需要手動編輯@param,有幾個參數(shù)需要編輯幾個。

變量和常量注釋
下面幾種情況下的常量和變量,都要添加注釋說明,在上方添加注釋。//和內容后面有一個空格。
- 接口中定義的所有常量
- 公有類的公有常量
- 枚舉類定義的所有枚舉常量
- 實體類的所有屬性變量
// 普通用戶
public static final int TYPE_COMMON_USER = 1;
// 管理員用戶
public static final int TYPE_ADMIN_USER = 2;
書寫規(guī)范
編碼方式
編碼方式統(tǒng)一用UTF-8. Android Studio默認已是UTF-8,只要不去改動它就可以了。
縮進
縮進統(tǒng)一為4個空格
花括號書寫
- 左大括號前不換行
- 左大括號后換行
- 右大括號前換行
- 如果右大括號是一個語句、函數(shù)體或類的終止,則右大括號后換行; 否則不換行
例如,如果右大括號后面是else或逗號,則不換行。
return new MyClass() {
@Override public void method() {
if (condition()) {
try {
something();
} catch (ProblemException e) {
recover();
}
}
}
};
空格的使用
if、else、for、switch、while等邏輯關鍵字與后面的語句留一個空格隔開。
if (booleanVariable) {
// TODO while booleanVariable is true
} else {
// TODO else
}
運算符兩邊各用一個空格隔開。
int result = a + b; //Good, = 和 + 兩邊各用一個空格隔開
int result=a+b; //Bad,=和+兩邊沒用空格隔開
方法的每個參數(shù)之間用一個空格隔開。
public void method(String param1, String param2); // Good,param1后面的逗號與String之間隔了一個空格
method(param1, param2); // Good,方法調用時,param1后面的逗號與param2之間隔了一個空格
method(param1,param2); // Bad,沒有用一個空格隔開
空行的使用
將邏輯相關的代碼段用空行隔開,以提高可讀性??招幸仓豢找恍?,不要空多行。在以下情況需用一個空行:
- 兩個方法之間
- 方法內的兩個邏輯段之間
- 方法內的局部變量和方法的第一條邏輯語句之間
- 常量和變量之間
表達式過長書寫
當一個表達式無法容納在一行內時,可換行顯示,另起的新行用8個空格縮進。
someMethod(longExpression1, longExpression2, longExpression3,
longExpression4, longExpression5);
變量聲明
一行聲明一個變量,不要一行聲明多個變量,這樣有利于寫注釋。
// 參數(shù)1
private String param1;
// 參數(shù)2
private String param2;
行寬設置
行寬設置為100,設置格式化時自動斷行到行寬位置。

方法規(guī)模
一個方法最多不要超過40行代碼(官方建議)。
常量定義
常量統(tǒng)一采用接口來定義,按模塊和類型等劃分。
文字和元素大小單位定義
官方建議文字大小的單位統(tǒng)一用sp,元素大小的單位統(tǒng)一用dp。從實際開發(fā)中看,文字大小采用sp,會導致文字大小隨著系統(tǒng)設置字體的大小變化,導致布局出問題。因此我們項目組初期采用的都是使用dp,但目前使用的是以1280*720基準尺寸,橫坐標分成1280份,縱坐標分成720份,其他按比例進行伸縮,實際是以px為單位處理。
字符串定義
應用中的字符串統(tǒng)一在strings.xml中定義,然后在代碼和布局文件中引用。
顏色定義
顏色值統(tǒng)一在colors.xml中定義,然后在代碼和布局文件中引用。另外,不要在代碼和布局文件中引用系統(tǒng)的顏色,除了透明。
命名規(guī)范
包命名
域名反寫+項目名稱+模塊名稱,全部單詞用小寫字母。
例如
com.android.example.login
類和接口命名
使用大駝峰規(guī)則,用名詞或名詞詞組命名,每個單詞的首字母大寫。
以下為幾種常用類的命名:
- activity類,命名以Activity為后綴,如:LoginActivity
- fragment類,命名以Fragment為后綴,如:ShareDialogFragment
- service類,命名以Service為后綴,如:DownloadService
- adapter類,命名以Adapter為后綴,如:CouponListAdapter
- 工具類,命名以Util為后綴,如:EncryptUtil
- 模型類,命名以Model為后綴,如:LoginModel
- 接口實現(xiàn)類,命名以Impl為后綴,如:ApiImpl
方法命名
使用小駝峰規(guī)則,用動詞命名,第一個單詞的首字母小寫,其他單詞的首字母大寫。
以下為幾種常用方法的命名:
- 初始化方法,命名以init開頭,例:initView
- 按鈕點擊方法,命名以onClick開頭,例:onclickLogin
- 設置方法,命名以set開頭,例:setData
- 具有返回值的獲取方法,命名以get開頭,例:getData
- 通過異步加載數(shù)據(jù)的方法,命名以load開頭,例:loadData
- 布爾型的判斷方法,命名以is或has,或具有邏輯意義的單詞如equals,例:isEmpty
控件縮寫
| 控件 | 縮寫 | 控件 | 縮寫 |
|---|---|---|---|
| TextView | TV | EditText | ET |
| Button | Btn | ImageButton | IBt |
| ImageView | IV | ListView | LV |
| ProgressBar | PB | SeekBar | SB |
| CheckBox | CB | LinearLayout | LL |
| Relativelayout | RL | FrameLayout | FL |
| ScrollView | SV | GridView | GV |
常量命名
全部為大寫單詞,單詞之間用下劃線分開。
public final static int PAGE_SIZE = 20;
變量命名
{范圍描述+}意義描述+類型描述的組合,用駝峰式,首字母小寫
- 非公開且非靜態(tài)字段的名稱以 m 開頭。
- 靜態(tài)字段的名稱以 s 開頭。
- 其他字段以小寫字母開頭。
- 公開靜態(tài) final 字段(常量)為全部大寫并用下劃線連接 (ALL_CAPS_WITH_UNDERSCORES)。
例如:
public class MyClass {
public static final int SOME_CONSTANT = 42;
public int publicField;
private static MyClass sSingleton;
int mPackagePrivate;
private int mPrivate;
protected int mProtected;
}
控件id命名
控件縮寫{范圍}意義,范圍可選,只在有明確定義的范圍內才需要加上。
<!-- 這是標題欄的標題 -->
<TextView
android:id="@+id/tv_header_title"
... />
<!-- 這是登錄按鈕 -->
<Button
android:id="@+id/btn_login"
... />
layout命名
組件類型{范圍}功能,范圍可選,只在有明確定義的范圍內才需要加上。
以下為幾種常用的組件類型命名:
- activity_{范圍_}功能,為Activity的命名格式
- fragment_{范圍_}功能,為Fragment的命名格式
- dialog_{范圍_}功能,為Dialog的命名格式
- item_list_{范圍_}功能,為ListView的item命名格式
- item_grid_{范圍_}功能,為GridView的item命名格式
- header_list_{范圍_}功能,為ListView的HeaderView命名格式
- footer_list_{范圍_}功能,為ListView的FooterView命名格式
strings的命名
模塊類型{范圍_}功能,范圍可選。
以下為幾種常用的命名(以登錄模塊為例):
- 頁面標題,命名格式為:login_title_頁面
- 按鈕文字,命名格式為:login_btn_按鈕事件
- 標簽文字,命名格式為:login_label_標簽文字
- 選項卡文字,命名格式為:login_tab_選項卡文字
- 消息框文字,命名格式為:login_toast_消息
- 編輯框的提示文字,命名格式為:login_hint_提示信息
- 圖片的描述文字,命名格式為:login_desc_圖片文字
- 對話框的文字,命名格式為:login_dialog_文字
- menu的item文字,命名格式為:login_action_文字
colors的命名
前綴{控件}{范圍}{_后綴},控件、范圍、后綴可選,但控件和范圍至少要有一個。例如bg_btn_send_normal
- 背景顏色,添加bg前綴
- 文本顏色,添加text前綴
- 分割線顏色,添加div前綴
- 公共的顏色,添加common前綴
- 區(qū)分狀態(tài)時,默認狀態(tài)的顏色,添加normal后綴
- 區(qū)分狀態(tài)時,按下時的顏色,添加pressed后綴
- 區(qū)分狀態(tài)時,選中時的顏色,添加selected后綴
- 區(qū)分狀態(tài)時,不可用時的顏色,添加disable后綴
drawable的命名
前綴{控件}{范圍}{_后綴},控件、范圍、后綴可選,但控件和范圍至少要有一個。
- 圖標類,添加ic前綴
- 背景類,添加bg前綴
- 分隔類,添加div前綴
- 默認類,添加def前綴
- 區(qū)分狀態(tài)時,默認狀態(tài),添加normal后綴
- 區(qū)分狀態(tài)時,按下時的狀態(tài),添加pressed后綴
- 區(qū)分狀態(tài)時,選中時的狀態(tài),添加selected后綴
- 區(qū)分狀態(tài)時,不可用時的狀態(tài),添加disable后綴
- 多種狀態(tài)的,添加selector后綴(一般為ListView的selector或按鈕的selector)
動畫文件命名
動畫類型_動畫方向。
- fade_in,淡入
- fade_out,淡出
- push_down_in,從下方推入
- push_down_out,從下方推出
- slide_in_from_top,從頭部滑動進入
- zoom_enter,變形進入
- shrink_to_middle,中間縮小
編程實踐
@Override:能用則用
只要是合法的,就把@Override注解給用上。
捕獲的異常:不能忽視
除了下面的例子,對捕獲的異常不做響應是極少正確的。(典型的響應方式是打印日志,或者如果它被認為是不可能的,則把它當作一個 AssertionError 重新拋出。)
如果它確實是不需要在catch塊中做任何響應,需要做注釋加以說明(如下面的例子)。
try {
int i = Integer.parseInt(response);
return handleNumericResponse();
} catch (NumberFormatException ok) {
// it's not numeric; that's fine, just continue
}
return handleTextResponse(response);
例外:在測試中,如果一個捕獲的異常被命名為expected,則它可以被不加注釋地忽略。下面是一種非常常見的情形,用以確保所測試的方法會拋出一個期望中的異常,因此在這里就沒有必要加注釋。
try {
emptyStack.pop();
fail();
} catch (NoSuchElementException expected) {
}
使用 TODO 備注
為代碼使用 TODO 備注是短期的臨時解決方案,或者說足夠好但并不完美。TODO 備注應該以全部大寫的字符串 TODO 開頭,后跟一個冒號:
// TODO: Remove this code after the UrlTable2 has been checked in.
和
// TODO: Change this to use a flag instead of a constant.
如果TODO 采用“在未來的某個日期做某事”的形式,請確保在其中包含一個非常具體的日期(“在 2005 年 11 月前修復”)或者一個非常具體的事件(“在所有生產(chǎn)環(huán)境合成器都可處理 V7 協(xié)議后移除此代碼”)。
靜態(tài)成員:使用類進行調用
使用類名調用靜態(tài)的類成員,而不是具體某個對象或表達式。
Foo aFoo = ...;
Foo.aStaticMethod(); // good
aFoo.aStaticMethod(); // bad
somethingThatYieldsAFoo().aStaticMethod(); // very bad
Finalizers: 禁用
極少會去重載Object.finalize。
Tip:
不要使用finalize。如果你非要使用它,請先仔細閱讀和理解Effective Java第7條款:"Avoid Finalizers",然后不要使用它。
謹慎使用日志記錄
項目中請不要直接使用Log打印日志,應該至少對系統(tǒng)日志封裝一個日志類,該類可以控制當前打印輸出的日志級別或者打開和關閉日志打印。每個類定義一個常量TAG用來打印相應的類的日志,當功能開發(fā)穩(wěn)定之后,請去掉開發(fā)打印的調試日志。
保持一致
總而言之:保持一致。如果正在修改代碼,花幾分鐘時間看一下周圍的代碼并確定其樣式。如果該代碼在 if 語句周圍使用空格,那么您也應該這樣做。如果代碼備注的周圍是用星號組成的小方框,您也應該將備注放在這樣的小方框內。