Android開發編碼規範

第一章 緒論

1.1概述 

編碼規範對於程序員而言尤爲重要,有以下幾個原因: 

【原因1】一個軟件的生命週期中,80%的花費在於維護。 

【原因2】幾乎沒有任何一個軟件,在其整個生命週期中,均由最初的開發人員來維護。 

【原因3】編碼規範可以改善軟件的可讀性,可以讓程序員儘快而徹底地理解新的代碼。 

……等等很多原因,不一一列舉。

1.2目的 

統一規範Eclipse/studio編輯環境下android的編碼風格和標準。此爲最基本的編碼要求規範,包括文件、註釋、命名規範,必須完全遵守。

1.3適用範圍 

適用於安卓手機APP項目。

第二章 命名註釋規範

2.1 命名規範

2.1.1 包命名 

命名規則:包名採用域後綴倒置的加上自定義的包名,採用小寫字母,都應該以com.*(公司名)開頭(不包括一些特殊原因)。在部門內部應該規劃好包名的範圍,防止產生衝突。部門內部產品使用部門的名稱加上模塊名稱。產品線的產品使用產品的名稱加上模塊的名稱。 

說明:除特殊原因包結構都必須以com.*開頭,已有項目包結構不做調整. 

格式: 

com.公司名.產品名.模塊名稱

2.1.2 類和接口命名 

規則一:命名必須使用駝峯規則,即每個英文單詞的首字母使用大寫、其餘字母使用小寫的大小寫混合法,類名和接口使用類意義完整的英文描述,不允許出現無意義的單詞,如(FirstActivity),應該爲(LauncherActivity)。 

示例:ChatActivity, LogManager, LogConfig 

規則二:常用組件類的命名以組件名加上組件類型名結尾。 

示例: 

Application 類型的,命名以Application 結尾——MTApplication 

Activity類型的,命名以Activity結尾——LoginActivity 

fragment類型的,建議命名以fragment結尾——CourseFragment 

adapter類型的,建議命名以adapter 結尾——ContactDetailAdapter 

bean 類型的,請求體,建議命名以Req結尾-GetMMSListReq,消息返回提,建議以Resp結尾-BackupProgressResp。

2.1.3 方法命名 

規則一:方法名是一個動詞,採用大小寫混合的方式,第一個單詞的首字母小寫,其後單詞的首字母大寫,並且方法名使用類意義完整的英文描述。 

示例: 

public void addNewOrder(); 

規則二:方法中,存取屬性的方法採用set 和 get方法,動作方法採用動詞和動賓結構,類的布爾型的判斷方法一般要求方法名使用單詞 is或has 做前綴。 

格式: 

set + 屬性名() 

get + 非布爾屬性名() 

動詞() 

動詞 + 賓語() 

is + 布爾屬性名() 

示例: 

public void setVisible(boolean); 

public String getType(); 

public void show(); 

public void addKeyListener(Listener); 

public boolean isFinished(); 

規則三:如果函數名超過15 個字母,可採用以去掉元音字母的方法或者以行業內約定俗成的縮寫方式縮寫函數名。 

示例: 

getCustomerInformation() 改爲 getCustomerInfo()

2.1.4 屬性名 

規則一:屬性名使用意義完整的英文描述,變量名應簡短且富於描述,第一個單詞的字母使用小寫,剩餘單詞首字母大寫其餘字母小寫的大小寫混合法。儘量避免單個字符的變量名,除非是一次性的臨時變量。 

示例: 

private customerName; 

private orderNumber; 

private smpSession; 

規則二:含有集合意義的屬性命名,儘量包含其複數的意義。 

示例: 

customers, orderItems

2.1.5 常量名 

規則一:常量名使用全大寫的英文描述,英文單詞之間用下劃線分隔開,並且使用 static final修飾。 

示例: 

public static final int MAX_VALUE = 1000; 

public static final String DEFAULT_START_DATE = “2001-12-08”;

2.1.6 layout 命名 

規則一:layout xml 的命名必須以 全部單詞小寫,單詞間以下劃線分割,並且使用名詞或名詞詞組,即使用 模塊名_功能名稱 來命名。 

示例: 

person_login.xml

2.1.7 id 命名 

規則一:layout 中所使用的id必須以全部單詞小寫,單詞間以下劃線分割,並且使用名詞或名詞詞組,並且要求能夠通過id直接理解當前組件要實現的功能。 

示例: 

@+id/book_name_show 

@+id/book_name_edit

2.1.8 資源命名 

規約:layout中所使用的所有資源(如drawable,style等)命名必須以全部單詞小寫,單詞間以下劃線分割,並且儘可能的使用名詞或名詞組,即使用 模塊名_用途 來命名。如果爲公共資源,如分割線等,則直接用用途來命名 

示例: 

home_icon_username.png 

home_icon_confirm.png 

line.png或 default_image.png 

Home_register_sumbit_bg_selector

2.2 註釋規範 

2.2.1 基本原則 

源程序註釋量必須在30%以上。由於每個文件的代碼註釋不一定都可以達到30%,建議以一個系統內部模塊作爲單位進行檢查。

2.2.2 基本概念 

Java 程序有兩類註釋:實現註釋(implementation comments)和文檔註釋(document comments)。實現註釋是使用//和//界定的註釋。文檔註釋(被稱爲”doc comments”)由/*…/界定。文檔註釋可以通過javadoc 工具轉換成HTML 文件。

2.2.3 文件註釋 

規則一:包的註釋:寫入一個名爲 package.html 的HTML格式的說明文件放入包所在路徑。包的註釋內容:簡述本包的作用、詳細描述本包的內容、產品模塊名稱和版本、公司版權。(目前不涉及到對外開放源碼,可以暫時不添加) 

說明:方便JavaDoc收集,方便對包的瞭解 

示例: 

/* 

* 文件名 

* 包含類名列表 

* 版本信息,版本號 

* 創建日期。 

* 版權聲明 

*/

2.2.4 類註釋 

規則一:類和接口的註釋放在class 或者 interface 關鍵字之前,import 關鍵字之後。註釋主要是一句話功能簡述與功能詳細描述。類註釋使用“//”註釋方式 

說明:方便JavaDoc收集,沒有import可放在package之後。註釋可根據需要列出:作者、內容、功能、與其它類的關係等。功能詳細描述部分說明該類或者接口的功能、作用、使用方法和注意事項,每次修改後增加作者和更新版本號和日期,@since 表示從那個版本開始就有這個類或者接口。

/** 

* 〈功能詳細描述〉 

* @version [版本號, 創建時間] 

* @author [作者](必須) 

* @see [相關類/方法](可選) 

* @since [產品/模塊版本] (必須) 

*/

示例: 

/** 

* <推送相關字段> 

* @author caoyinfei 

* @version [版本號, 2016/5/23] 

* @see [相關類/方法] 

* @since [V39] 

*/

2.2.5 方法註釋 

規則一:每一個方法都要包含 如下格式的註釋 包括當前方法的用途,當前方法參數的含義,返回參數的含義。 

示例: 

/** 

* <判斷對象是否爲null> 

* @param 需要判斷的對象 

* @return 爲null返回true,否則返回false 

*/ 

public static boolean isNull(Object obj) 

return (null == obj) ? true : false; 

}

2.2.6類變量註釋 

規則一:成員變量和常量需要使用java doc形式的註釋,以說明當前變量或常量的含義,註釋方式爲“//”。 

示例: 

/** 

* 密碼輸入框 

*/

2.2.7 其他註釋 

規則一:方法內部的註釋 如果需要多行 使用/…… /形式,如果爲單行是用//……形式的註釋。不要再方法內部使用 java doc 形式的註釋“/……/”。 

關鍵跳轉需要在代碼上方加上註釋 

示例: 

@Override 

public void onClick(View v) 

switch (v.getId()) 

/* 

* 響應返回按鈕 

*/ 

case R.id.title_back_layout: 

// 關閉當前頁面 

finish(); 

break; 

/* 

* 響應登陸按鈕 

*/ 

case R.id.login: 

break; 

/* 

* 響應註冊按鈕 

*/ 

case R.id.title_call_layout: 

break; 

/* 

* 響應忘記密碼按鈕 

*/ 

case R.id.forget_password: 

break; 

default: 

break; 

}

2.2.8 XML註釋

第三章 編碼規範

3.1 對象釋放 

規則一:數據庫操作、IO操作等需要使用結束close()的對象必須在try -catch-finally 的finally中close(),如果有多個IO對象需要close(),需要分別對每個對象的close()方法進行try-catch,防止一個IO對象關閉失敗其他IO對象都未關閉。 

示例: 

try 

// … … 

catch(IOException ioe) 

//… … 

finally 

try 

out.close(); 

catch (IOException ioe) 

//… … 

}

try 

in.close(); 

catch (IOException ioe) 

//… … 

}

規則二:集合中的數據如果不使用了應該及時釋放,尤其是可重複使用的集合。 

說明:由於集合保存了對象的引用,虛擬機的垃圾收集器就不會回收。

3.2 異常處理 

規則一:系統非正常運行產生的異常捕獲後,如果不對該異常進行處理,則應該記錄日誌。 

說明:此規則指通常的系統非正常運行產生的異常,不包括一些基於異常的設計。若有特殊原因必須用註釋加以說明。 

示例: 

try 

//…. … 

catch (IOException ioe) 

logger.error(ioe); 

}

3.3 魔鬼數字 

規則一:避免使用不易理解的數字,用有意義的標識來替代。涉及物理狀態或者含有物理意義的常量,不應直接使用數字,必須用有意義的靜態變量或者枚舉來代替。 

示例:如下的程序可讀性差。 

if (state == 0) 

state = 1; 

… // program code 

}

應改爲如下形式: 

private final static int TRUNK_IDLE = 0; 

private final static int TRUNK_BUSY = 1; 

private final static int TRUNK_UNKNOWN = -1;

if (state == TRUNK_IDLE) 

state = TRUNK_BUSY; 

… // program code 

}

3.4 控制檯輸出 

規則一:不要使用 System.out和系統logger 進行控制檯打印,應該使用統一封裝的工具類(如:公共日誌工具)進行統一記錄或者打印。 

說明:代碼發佈的時候可以統一關閉控制檯打印,代碼調試的時候又可以打開控制檯打印,方便調試。 

規則二:用調測開關來切換軟件的DEBUG版和正式版,而不要同時存在正式版本和DEBUG版本的不同源文件,以減少維護的難度。

3.5 類的定義 

規則一:一個文件不要定義兩個類(並非指內部類)。 

說明:方便程序的閱讀與代碼的維護

3.6 判斷語句 

規則一:判斷語句不要使用”* == true”來判斷爲真 

說明:方便閱讀,減少沒有必要的計算 

以下錯誤: 

if (ok == true) 

…… 

以下正確: 

if (ok) 

…… 

規則二:常量放在equals的前面,防止空指針異常。 

示例: 

if (“abc”.equals(bean.getName())) 

…… 

說明:如果爲bean.getName().equals(“abc”),當bean.getName()爲null時,則會拋出空指針異常。

3.7 向上轉型 

規則一:不要寫沒有必要的向上強制轉型。 

說明:沒必要寫的向上強制轉型會浪費性能,增加代碼閱讀難度 

示例:以下錯誤: 

FileInputStream fis = new FileInputStream(f); 

InputStream is = (InputStream)fis;

3.8 重複代碼 

規則一:如果多段代碼重複做同一件事情,那麼在方法的劃分上可能存在問題。 

說明:若此段代碼各語句之間有實質性關聯並且是完成同一件功能的,那麼可考慮把此段代碼構造成一個新的方法。

3.9 代碼複雜度 

規則一:不要使用難懂的技巧性很高的語句,除非很有必要時。 

說明:高技巧語句不等於高效率的程序,實際上程序的效率關鍵在於設計與算法。 

規則二:明確方法功能,精確(而不是近似)地實現方法設計。一個函數僅完成一件功能,即使簡單功能也編寫方法實現。 

說明:雖然爲僅用一兩行就可完成的功能去編方法好象沒有必要,但用方法可使功能明確化,增加程序可讀性,亦可方便維護、測試。 

規則三:類中成員函數的圈複雜度不大於15。 

規則四:一個方法只完成一項功能,在定義系統的公用接口方法外的方法應儘可能的縮小其可見性。避免用一個類是實例去訪問其靜態變量和方法。避免在一個較長的方法裏提供多個出口: 

示例: 

//不要使用這鐘方式,當處理程序段很長時將很難找到出口點 

if(condition) 

return A; 

else 

return B; 

//建議使用如下方式 

String result = null; 

if(condition) 

result = A; 

else 

result = B; 

return result;

3.10 枚舉的使用 

規則一:2.3之前的枚舉效率很低,後面google優化了,枚舉可以放心使用,效率沒有太大差別。

3.11 參數和返回值 

規則一:避免過多的參數列表,儘量控制在 5 個以內,若需要傳遞多個參數時,當使用一個容納這些參數的對象進行傳遞,以提高程序的可讀性和可擴展性。參數類型和返回值儘量接口化,以屏蔽具體的實現細節,提高系統的可擴展性,例如: 

public void joinGroup(List userList){} 

public List listAllUsers(){}

第四章 性能與安全

4.1 基本原則 

性能的提升並不是一蹴而就的,而是由良好的編程積累的,雖然任何良好的習慣和經驗所提升的性能都十分有限,甚至微乎其微,但良好的系統性能卻是由這些習慣等積累而成,android性能優化涉及到大篇幅的介紹跟講解,這邊只是簡單列舉出幾個。

4.2 String 與 StringBuffer 

不要使用如下 String 初始化方法: String str = new String(“abcdef”);這將產生兩個對象,應當直接賦值: String str = “abcdef”; 

在處理可變 String 的時候要儘量使用 StringBuffer 類,StringBuffer 類是構成 String類的基礎。String 類將 StringBuffer 類封裝了起來,(以花費更多時間爲代價)爲開發人員提供了一個安全的接口。當我們在構造字符串的時候,我們應該用 StringBuffer 來實現大部分的工作,當工作完成後將 StringBuffer 對象再轉換爲需要的 String 對象。比如:如果有一個字符串必須不斷地在其後添加許多字符來完成構造,那麼我們應該使用 StringBuffer 對象和她的append() 方法。如果我們用 String 對象代替 StringBuffer 對象的話,將會花費許多不必要的創建和釋放對象的 CPU 時間。

4.3 集合 

避免使用 Vector 和 HashTable 等舊的集合實現,這些實現的存在僅是爲了與舊的系統兼容,而且由於這些實現是同步的,故而在大量操作時會帶來不必要的性能損失。在新的系統設計中不當出現這些實現,使用 ArrayList 代替 Vector,使用 HashMap 代替 HashTable。 

若卻是需要使用同步集合類,當使用如下方式獲得同步集合實例: 

Map map = Collections.synchronizedMap(new HashMap()); 

由於數組、ArrayList 與 Vector 之間的性能差異巨大,故在能使用數組時不要使用 ArrayList,儘量避免使用 Vector。 

我們經常會使用到HashMap這個容器,它非常好用,但是卻很佔用內存,Android提供了內存效率更高的ArrayMap。

4.4 對象 

避免在循環中頻繁構建和釋放對象。不再使用的對象應及時銷燬。如無必要,不要序列化對象。

4.5 同步 

在不需要同步操作時避免使用同步操作類,如能使用 ArrayList 時不要使用 Vector。儘量少用同步方法,避免使用太多的 synchronized 關鍵字。儘量將同步最小化,即將同步作用到最需要的地方,避免大塊的同步塊或方法等。

4.6避免使用Static對象 

因爲static的生命週期過長,使用不當很可能導致leak,在Android中應該儘量避免使用static對象。

4.7 layout嵌套層次 

你可以在手機打開 設置—->開發者選項—->顯示GPU過度繪製,這個開關的作用是按不同顏色值來顯示佈局的過度繪製,繪製的層次從最優到最差:藍,綠,淡紅,紅。一般佈局層次不宜過多,一般保持在綠色爲比較優的界面佈局。 

減少佈局層次可以從以下幾個方面: 

1.實現複雜的佈局時,儘量使用RelativeLayout ,由於 RelativeLayout 所需要的嵌套層次少,控件平鋪是最終努力的方向,這樣性能會好一些。 

2.ViewStub的使用,viewStub是一個輕量級的頁面,我們通常使用它來做預加載處理,來改善頁面加載速度和提高流暢性,ViewStub本身不會佔用層級,它最終會被它指定的層級取代。 看到頁面佈局裏面很多gone的控件,即使是將某一個控件的visibility屬性設置爲不可見的gone,在整個頁面加載過程中還是會加載此控件的。

摘自:http://blog.csdn.net/dfskhgalshgkajghljgh/article/details/51670081

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章