Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android開發編碼規范

Android開發編碼規范

編輯:關於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,在整個頁面加載過程中還是會加載此控件的。

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved