android規范文檔,請勿轉載!謝謝...
1. 概述
1.1 前言
團隊協作能夠顯著有效的提高工作效率,而代碼規范在團隊協作當中也起了很重要的作用;這份文檔參考了Google Java 編程風格規范和Google官方Android編碼風格規范。該文檔僅供參考,適用于android團隊。1.2 目的
形成統一的代碼規范,減少編碼過程中bug的數量,增加代碼的觀賞性、擴展性以及可維護性。
2. 開發準備
2.1 開發工具使用android studio。
2.2 代碼管理使用管理工具git以及git flow思想進行管理。
3. 代碼風格
- 3.1 文件格式和文件類型
utf-8格式和java文件。
- 3.2 程序塊縮進
不以tab進行縮行處理,以space空格鍵進行縮行
- 3.3 程序塊空行
a.空行將邏輯相關的代碼塊分隔開,以提高可讀性。
b.一個源文件的兩個片段之間。
c.類聲明和接口聲明之間。
d.兩個方法之間。
e.方法內的布局變量與方法的第一條語句之間。
f.一個方法內的兩個邏輯段之間。
- 3.4 長語句與長表達式
循環或判斷當中若是有較長的表達式或語句,要進行適當的劃分,一般
以操作符為分割對象,操作符位于分隔行之首。
- 3.5 長參數
方法當中有多個參數時,以方法內部逗號進行劃分,逗號位于分隔行之首。
- 3.6 短語句
每行只能存在一條語句,每條語句結束后應當進行換行處理。
- 3.7 大括號{}的使用
a.大括號一般與if else 、for、do while語句一起使用,即便是一條空語句
也應該把大括號加上。
b.左大括號前不換行、左大括號后換行、右大括號前換行
c.如果右大括號后是一個語句、函數體或類的終止,則右大括號后換行,否則不換行。
public void method() {//Good
}
public void method(){//Bad
}
public void method()//Bad{
}
- 3.8 自動換行
一般情況下,一行長代碼為了避免超出列限制(80或100個字符)而被分成多行,很多時候,對于同一串代碼已經有了好幾種有效的自動換行方式。
- 3.9 變量聲明
不要使用組合聲明。如:int i, j,k;
int i, j, k;//Bad
int i;//Good
int j;//Good
- 3.10 參數和返回值
a.一個方法的參數盡量不易過多,如若過多,做好換行處理
public void method(String params01 , String params02
, String params03…) {
}//good
b.一個方法返回值是錯誤碼,用異常處理去替代它
c.盡可能不要使用null,替代為異常或者空變量,List則可以返回Collections.emptyList形式。
- 3.11 import語句
a.impory語句不使用通配符,不換行。
import java.lang.*;//Bad
import java.lang.string;//Good
b.順序和間距
- Import語句可以分為以下幾組,按照這個順序,每組由一個空行分隔:
所有的靜態導入獨立成組
- com.google imports(僅當這個源文件是在com.google包下)
- 第三方的包。每個頂級包為一組,字典序。例如:android,com,jnuit,org,
sun
- Java imports5.javax imports組內不空行,按字典序排序
- 3.12 使用標準的Java Annotation
a.Annotation位于java語言其它 修飾符之前。簡單的marker annotation(@Override等)可以和語言元素放在同一行。如果存在多個annotation,或者annotation是參數化的,則應該按字母順序各占一行來列出。
內建三種Annotation | Annotation注解內容 |
---|---|
@DePrecated | 只要某個語言元素已經不再建議使用了,必須使用@DePrecated annotation。如果使用了@Deprecated annotation ,則必須同時進行@Deprecated javadoc標記,并且給出一個替代的實現方案。此外,@Deprecated 的方法仍然是能正常執行的。 |
@Override | 只要某個方法覆蓋了已過時的或繼承自超類的方法,就必須使用@Override annotation。 |
@SuppressWarnings | @SuppressWarnings annotation 僅用于無法消除編譯警告的場合。如果警告確實經過測試”不可能消除”,則必須使用@SuppressWarnings annotation,已確保所有的代碼警告都能真實反映代碼中的問題。當需要使用@SuppressWarnings annotation時,必須在前面加上TODO注釋行,用于解釋“不可能解除警告”的條件 |
b.Todo注釋一般應用于未完成的功能區域。
c.對那些臨時性的、短期的、夠棒但不完美的代碼,使用TODO注釋
TODO注釋應該包含全部大寫的TODO,后跟一個冒號:
//TODO: Remove this Code for version code
//TODO: Change this Code for reason
d.注釋的語言當前以中文為主。
- 3.13 Java異常的處理
a.不要忽略異常,即使你的代碼看起來永遠不會出現這種情況或者處理這種異常并不重要,但忽略異常的這種行為會在代碼中埋下一顆定時炸彈,so,在代碼中以某種規矩處理所有的異常。
public void stringToInt(String value){
try{
int intValue = Integer.parseInt(value);
}catch(NumberFormatException){
}
}
空的catch語句在java中會讓人感到憂慮,絕對不要這樣做,替代方案有以下幾
種。
向方法的調用者拋出異常
public void stringToInt(String value) throws NumberFormatException{
int intValue = Integer.parseInt(value);
}
根據抽象級別拋出新的異常。
public void stringToInt(String value) throws SelfDefineException{
try{
int intValue = Integer.parseInt(value);
}catch(NumberFormatException){
throw new SelfDefineException(“value”+invalid number);
}
}
默默的處理錯誤并在catch中替換為合適的值。
public void stringToInt(String value){
int intValue;
try{
intValue = Integer.parseInt(value);
}catch(NumberFormatException){
intValue = 0;
}
}
b.不要捕獲頂級的Exception
絕大部分情況下,捕獲頂級的Exception或Throwable都是不合適的,Throwable更
不合適,因為它還包含了Error異常。
try{
ioOperationMethod();//may be throw IOException
classCastOperationMethod();//may be throw CastException
objectInvokeMethod();//may be throw NullPointException
}catch(Exception e){
handlerError();//just handler with one operation
}
不可直接全部捕獲為Exception異常,正常的處理方式為:
分開捕獲每一種異常,在一條try語句后面跟隨多個catch語句塊。
再次拋出異常,很多時候我們不需要捕獲這個異常,只要讓這個方法拋出這個異
常即可。
- 3.14 其它
4.命名規范
4.1 包名全部小寫,連續的單詞只是簡單的鏈接起來,不適用下劃線;采用反域名命名規則,一級包名為公司性質,二級包名為公司名或個人,三級包名為應用,四級包名為模塊名或層級名等。
4.2 類名采用大駝峰駝峰命名法,既采用功能名+類型名的命名方式,盡量避免縮寫,除非該縮寫是眾所周知的;如果類名眾包含縮寫單詞,則單詞縮寫的每個字母均為大寫。對于繼承自安卓組件的類來說,類名應該以該組件名結尾,例如 : SignInActivity , SignInFragment , ImageUploaderService , ChangePasswordDialog ;對于工具類來說,命名方式應該以其完成功能開始,以 Utils 結束 ,例如 : HttpUtils , ImageUtils .
類 | 包名 | 命名格式 | 示例 |
---|---|---|---|
Activity | *.ui.activity | 功能名+activity | MainActivity LoginActivity… |
Service | *.service | 功能名+Service | DownLoadService… |
BroadCastReceiver | *.service | 功能名+Receiver | JpushReceiver AlarmReceiver… |
Fragment | *.ui.fragment | 功能名+Fragment | MainFragment FoundFragment… |
Dialog | *.ui.widget | 功能名+Dialog | CustomDialog RoundProgressBar… |
Adapter | *.ui.adapter | 功能名+Adapter | GoodsAdapter CouponAdapter… |
基礎功能類 | *.app | Base+父類名 | BaseActivity BasePresenter… |
工具類和管理類 | *.ui.utils | 功能名+Utils/Manager | DbUtilsFileUtils… |
4.3 接口/抽象類命名方式和類名差不多,一般在接口類前加上大寫的I/A,表示這是一個Interface/Abstract類。例:IView,Ipresenter…
4.4 資源文件:以小寫加下劃線的方式命名
- 4.4.1 drawable文件的命名規范:
Asset Type | Prefix 前綴 | Example |
---|---|---|
Action bar | ab_ | ab_stacked.9.png |
Button | btn_ | btn_send_pressed.9.png |
Dialog | dialog_ | dialog_top.9.png |
Divider | divider_ | divider_horizontal.png |
Icon | ic_ | ic_star.png |
Menu | menu_ | menu_submenu_bg.9.png |
Notification | notification_ | notification_bg.9.png |
Tabs | tab_ | tab_pressed.9.png |
- 4.4.2 icons文件的命名規范:
Asset Type | Prefix 前綴 | Example |
---|---|---|
Icons | ic_ | ic_star.png |
Launcher icons | ic_launcher | ic_launcher.png |
Menu icons and Action Bar icons | ic_menu | ic_menu_archive.png |
Status bar icons | ic_stat_notify | ic_stat_notify_msg.png |
Tab icons | ic_tab | ic_tab_recent.png |
Dialog icons | ic_dialog | ic_dialog_info.png |
- 4.4.3 選擇器狀態文件的命名規范:
Asset Type | Prefix 前綴 | Example |
---|---|---|
Normal | _normal | btn_order_normal.png |
Pressed | _pressed | btn_order_pressed.png |
Focused | _focused | btn_order_focused.png |
Disabled | _disabled | btn_order_disabled.png |
Selected | _selected | btn_order_selected.png |
- 4.4.4 布局文件:
Component組件 | Class Name | Example |
---|---|---|
Activity | MainActivity | activity_main.xml |
Fragment | SiteFragment | Fragment_site.xml |
Dialog | LoadingDialog | dialog_loading.xml |
Adapter Item | item_site.xml | |
其他視圖 | view_head.xml |
- 4.4.5 string.xml、dimens.xml、colors.xml、styles.xml命名方式 ,遵循完整性 規范性 有序性原則,分塊注釋,不同模塊區分開:
- layout常量要在string.xml中進行定義,且每個常量根據功能模塊自成一組,如:
<!—我的關注-->
<string name=”cancel_follow”>取消關注</string>
…
<!—我的優惠劵-->
<string name=”no_used_toast”>您沒有未使用的優惠劵喲~</string>
…
- layout當中控件的margin、padding以及TextView的文本大小值定義在
dimens.xml
文件當中,sp采取的命名方式為size_具體數值,dp采取的命名方式為dp_具體數
值,如:
<dimen name=”size_10”>10sp</dimen>
…
<dimen name=”dp_10”>10dp</dimen>
…
layout當中的復用樣式定義到styles.xml當中。
- 4.4.6 動畫文件 :
動畫效果 | 命名風格 | Example |
---|---|---|
淡入/淡出 | fade_in/fade_out | fade_in.xml |
從右淡入 | fade_right_in | fade_right_in.xml |
從右彈入 | push_right_in | push_right_in.xml |
從右滑入 | slide_in_from_right | slide_in_from_right.xml |
- 4.5 類方法采用 小駝峰 命名法,根據函數所完成功能命名 ,如 changView(),在函數頭寫對于函數功能、參數和返回值的注釋,一個函數請盡量保持在50行 之內 如:
/**
* 獲取兩個數中最大的一個
* @param value1 參與比較的第一個數
* @param value2 參與比較的第二個數
* @return 兩個參數中最大的一個數
*/
public int max(int value1, int value2) {
return (value1 > value2) ? value1 : value2;
}
- 4.6 控件id命名
控件 | 前綴縮寫 |
---|---|
RelativeLayout | rl |
LinearLayout | ll |
FrameLayout | fl |
TextView | tv |
Button | btn |
ImageButton | ibtn |
ImageView | iv |
CheckBox | cb |
RadioButton | rb |
EditText | edt |
ToggleButton | tbtn |
ProgressBar | pb |
VideoView | vv |
WebView | wv |
ScrollView | sv |
ListView | lv |
GridView | gv |
RecycleView | rv |
- 4.7 變量名采用小駝峰命名
a.非公有,非靜態成員變量命名前面加m(member,表示成員變量之意),如,控件的寬高mWidth,mHeight
b.靜態類變量前面加s(static,表示靜態變量之意),如,一個靜態的單例sSingleInstance
c.公有非靜態字段命名以p開頭
d.公有靜態字段(全局變量)命名以g開頭
e.局部變量名
- 局部變量名以LowerCamelCase風格編寫,比起其它類型的名稱;局部變量可以
有更為寬松的縮寫。
- 雖然縮寫更寬松,但還是要避免用單字符進行命名,除了臨時變量和循環變量。
即使局部變量final是不可改變的,也不應該把它表示為常量,自然不能用常量的規
則去命名它。
- 臨時變量通常被取名為i,j,k,m和n,它們一般用于整型;c,d,e,它們一般
用于字符型。如:for(int i=0 ; i<len;i++),并且它和第一個單詞間沒有空格。
5. 編碼規范
- 5.1 Activity當中的onCreate方法分為三個部分
a.initVariable()?初始化變量以及獲取Intent傳值。
b.initViews()?控件的初始化操作。
c.presenter.getXXData()?當前界面的數據獲取操作。
- 5.2 布局的適配方案,xml當中的每個控件都得在activity當中初始化完畢后,重新調
取測量方法例:
- measure(mViewFoot,0,142)
- measure(mIvTabOne,78,78)
- measure(mIvTabTwo,78,78)
…
measure內部實現原理?
ViewGroup.LayoutParams params = view.getLayoutParams();
params.width = resetWidth;
params.height = resetHeight;
view.setLayoutParams(params);
5.3 使用retrofit+gson的形式定義module層的數據載體。
5.4 activity之間的傳值堅持用Intent攜帶序列化實體數據的方式。禁止為了省事使用全局變量進行傳值的方式。
5.5 為節省內存,使用ArrayList<>作為數據的承載體,而不是HashMap;HashMap<>由android自封裝的SparseArray<>進行取代。
5.6 Glide圖片處理框架,由 *.util.glid包下的GlideUtil類實現glide圖片處理方法的封裝
5.7 控件的點擊事件由代碼控制,簡單邏輯可以在xml文件中通過onclick標簽實現.
5.8 SharePreferences只用于簡單的配置消息,對于對象,還是需要保存在本地文件中。
5.9 項目當中的單一圓角背景圖片,使用自定義shape進行處理。
5.10 數據庫采用項目中自定義的腳本進行表的創建刪除以及數據的增刪改查操作。
- 腳本升級文件的命名方式 (dbName_oldVer_newVer),如:test.db_1_2?表
示將test數據庫版本從1升到2。
- 數據庫中表的命名規范,全部大寫,單詞用下劃線_鏈接。
增加表的升級腳本
@orm.create(test1)
@orm.create(test2);
@orm.create(test3);
- 刪除表的升級腳本
drop table if exists TEST1_FIELD;
drop table if exists TEST2_FIELD;
drop table if exists TEST3_FIELD;
- 如果表中有增加、減少、修改列(對象對應的字段增加、減少、修改)
drop table if exists test1;
@orm.create(test4);
//先刪除原先的表再創建
drop table if exists test2;
@orm.create(test5);
- 5.6 上線打包注意的細節
a.更改<meta-data…></meta-data>當中的請求接口,由測試環境更改為正式環境。
b.關閉app本身應用的log日志開關以及第三方sdk應用的log日志開關。
檢查應用的版本號,做版本號的遞增處理。
c.build.gradle文件當中 對minifyEnable做混淆的操作,在proguard-rules.pro做對應保留類的操作。
d.對比git coding上的master分支和feature分支代碼,檢查數據庫表是否有變化,如果有,通過腳本做對應的升級、修改數據庫版本號以及測試數據庫相關更改是否通過。