從這篇文章開始咱們暫停一下對Android源碼的分析,開始講一下android產品研發中一些經常使用的技術,技巧,方法,實踐等姿式。這裏須要強調的是咱們所講解的這些東西可能對產品開發中比較經常使用的,由於對於項目開發中,可能更多的強調管理,進度方法的東西,對工程化的東西比較強調,而咱們這裏更多的是對產品技術方面的概括總結。java
而本文中選擇將開發規範做爲這個系列的第一篇文章,就是我的感受產品研發過程當中,開發規範真的很重要,很重要,很是重要(重要的事情說三遍),一個好的開發規範可讓團隊中的人對他人的代碼更熟悉,新人也能夠更好的瞭解產品的業務邏輯。開發規範並非一個死的一成不變的,每一個團隊可能都有本身的開發規範,只要是適合團隊的開發規範就是最好的開發規範。android
因此本文中所講解的開發規範只能是拋磚引玉,有可取的地方能夠借鑑,引用,不能照搬全抄不假思索,畢竟不一樣的團隊有不一樣的實際狀況。最好的方式就是能夠根據本文的開發規範總結出自身團隊比較適合的規範流程。程序員
好吧,廢話很少說了,下面咱們就介紹一下我在實踐中總結的android開發規範。算法
1 前言數據庫
1.1 爲何須要開發規範express
編碼規範對於程序員而言尤其重要,有如下幾個緣由:編程
* 一個軟件的生命週期中,80%的花費在於維護網絡
* 幾乎沒有任何一個軟件,在其整個生命週期中,均由最初的開發人員來維護 ide
* 編碼規範能夠改善軟件的可讀性,可讓程序員儘快而完全地理解新的代碼函數
* 若是你將源碼做爲產品發佈,就須要確任它是否被很好的打包而且清晰無誤,一如你已構建的其它任何產品
1.2 開發規範的做用
* 減小維護花費
* 提升可讀性
* 加快工做交接
* 減小名字增生
* 下降缺陷引入的機會
2 命名規範
2.1 常量命名規範
2.1.1 類型
常量命名規範
2.1.2 說明
常量用於保存須要常駐內存中而且常用變化很少的數據,定義常量的名稱的時候須要遵循望文知意的原則;
2.1.3 規則
所有爲大寫字母;
中間以「_」鏈接;
望文知意原則;
2.1.4 備註
代碼中涉及到直接使用某個字符串或者其餘基本類型的值時,建議定義成常量,避免多處直接使用一樣的值做爲參數。
2.1.5 舉例
如:定義一個常量表示最小屏幕寬度的常量,則能夠定義一個int類型的常量,該常量能夠命名爲:「MIN_SCREEN_WIDTH「;
其餘舉例:
例如:static final int MIN_SCREEN_WIDTH = 4;( √)
例如:static final int min_screen_width = 4;(×)
例如:static final int minScreenWidth = 4; (×)
例如:static final int WIDTH = 4;(×)
例如:static final int width = 4;(×)
例如:static final int wd = 4;(×)
2.2 變量命名規範
2.2.1 類型
變量命名規範
2.2.2 說明
變量用於保存系統中的臨時數據,變量命名時遵循望文知意,簡單明瞭,駝峯標示等原則。
2.2.3 規則
首字母大寫;
java駝峯命名;
望文知意原則;
推薦引用類型變量添加前綴「m」;
若是是View組件變量,則組件名稱爲xml文件中定義的ID名稱去掉下劃線,下劃線後一位大寫;
2.2.4 備註
無
2.2.5 舉例
如:定義一個表示最小屏幕寬度的變量,則能夠定義一個int型的臨時變量爲:mMinScreenWidth;
例如:static final int mMinScreenWidth = 4; ( √)
例如:static final int minWidth = 4;(×)
例如:static final int screenWidth = 4;(×)
例如:static final int width = 4;(×)
例如:static final int min = 4; (×)
例如:static final int msw = 4; (×)
2.3 方法命名規範
2.3.1 類型
方法命名規範
2.3.2 說明
方法名的命名應該遵循簡單明瞭的原則;
2.3.3 規則
首字母小寫;
java駝峯命名;
簡單明瞭原則;
初始化View方法init*(每一個init作一件事)
2.3.4 備註
同時在方法的實現上,儘可能不要在一個方法中出現太多實現代碼,如一個方法有幾百行的實現邏輯,推薦在邏輯複雜時,按功能點拆分出多個方法,便於閱讀。
另外,出現功能同樣的實現邏輯,儘可能抽取公用方法,避免將實現邏輯複製到多個用到的地方。
2.3.5 舉例
如:定義一個獲取屏幕寬度的方法,依照上述原則,則能夠定義爲一個靜態方法:public static int getScreenWidth();
例如:public static int getScreenWidth();( √)
例如:public static int getscreenwidth();(×)
例如:public static int getScreenwidth();(×)
例如:public static int getWidth();(×)
例如:public static int getScreen();(×)
例如:public static int getSW();(×)
2.4 類命名規範
2.4.1 類型
類命名規範
2.4.2 說明
類名主要表示一個類的做用,須要簡明扼要,望文知意,而且首字母大寫。
2.4.3 規則
首字母大寫;
java駝峯命名;
望文知意原則;
可以說明類的功能和主要做用(註釋的做用);
Acitivity類以Acitivity結尾;
Fragment類以Fragment結尾;
Service類以Service結尾;
BroadcastReceiver類以Receiver結尾;
ContentProvider類以Provider結尾;
Application類以Application結尾;
自定義View類以Custom**View結尾;
自定義Adapter類以Adapter結尾;
adapter中的ViewHolder以Holder結尾;
實體Bean以Model結尾;
2.4.4 備註
無
2.4.5 舉例
如:定義一個獲取屏幕信息的工具類,則能夠定義爲public class ScreenUtils;
例如:public class ScreenUtils; ( √)
例如:public class Screenutils; (×)
例如:public class Screen; (×)
例如:public class screenutils; (×)
例如:public class screen; (×)
例如:public class su;(x)
2.5 接口命名規範
2.5.1 類型
接口命名規範
2.5.2 說明
接口命名須要簡單明瞭,長度不宜過長;
2.5.3 規則
首字母大寫(第二個字母也是大寫);
java駝峯命名;
望文知意原則;
建議在名稱前面追加「I」;
2.5.4 備註
I**Listener
I**CallBack
I**;
2.5.5 舉例
如:定義一個activity的方法接口,實現接口中的某些方法:public
interface IFunctionListener;
例如:public interface IFunctionListener;( √)
例如:public interface BaseActivity; (×)
例如:public interface Baseactivityinter; (×)
例如:public interface BaseInter; (×)
例如:public interface ActivityInter;(×)
2.6 包名規範
2.6.1 類型
包名規範
2.6.2 說明
用於分類管理類文件;
2.6.3 規則
全部字母小寫;
簡單明瞭,層級很深,沒有拼接的包名;
望文知意;
按功能劃分包名,如「個人」
工具類能夠劃分爲一個工具類的包名,utils,裏面能夠添加包名層級;
系統類的能夠劃分爲一個系統類的包,system,裏面能夠添加包名層級;
組件類的能夠劃分爲一個組件類的包,*,裏面添加adapter的包名,自定義view包名;
Service類的能夠劃分爲一個服務類的包,service,裏面能夠添加包名層級;
數據庫相關類能夠劃分爲一個數據庫類,db,裏面能夠添加數據庫相關類,Bean類,數據庫服務類等;
廣播類的能夠劃分爲廣播類的包,receiver,能夠放一些廣播相關的類;
網絡類相關的能夠劃分爲,network,放一些網絡相關的類;
Fragment類存放在fragment包下;
Activity類存放在Activity包下;
2.6.4 備註
無
2.6.5 舉例
無
2.7 目錄名稱規範
2.7.1 類型
目錄名稱規範
2.7.2 說明
主要是一些jar包,so文件的配置目錄名稱;
2.7.3 規則
所有爲小寫字母;
簡單明瞭;
望文知意;
駝峯表示;
2.7.4 備註
無
2.7.5 舉例
後期增長目錄的可能性很少,現列舉出系統中存在的目錄結構:
lib:第三方jar的保存路徑;
jniLibs:jni引用的so文件的目錄;
2.8 佈局文件名稱規範
2.8.1 類型
佈局文件名稱規範
2.8.2 說明
主要包含資源文件的命名問題;
2.8.3 規則
所有爲小寫字母;
中間以」_」鏈接;
望文知意原則;
佈局文件的開頭問類名;
列表項的xml佈局文件名稱:類名_item.xml;
activity類的xml文件名稱:類名_activity.xml;
fragment類的xml文件名稱:類名_fragment.xml;
自定義View的xml文件的名稱:類名_父類名.xml;
2.8.4 備註
無
2.8.5 舉例
如:如定義H5Activity的xml文件名稱,則能夠定義爲h5.xml;儘可能不使用大寫字母等。
2.9 drawable文件名稱規範
2.9.1 類型
drawable文件名稱命名規範
2.9.2 說明
主要包含資源文件的命名問題;
2.9.3 規則
所有爲小寫字母;
中間以」_」鏈接;
望文知意原則;
佈局文件的開頭問類名;
11_22_33_44,44:selector,shape(大概五六個,暫時不定義其餘的); 33:src、bg、color(可擴展,可爲空); 22:狀態名稱或者爲空;11:業務名稱
2.9.4 備註
無
2.9.5 舉例
無
2.10 資源ID規範
2.10.1 類型
資源ID命名規範
2.10.2 說明
各類資源ID的定義問題;
2.10.3 規則
所有爲小寫字母;
中間以」_」鏈接;
望文知意原則;
2.10.4 備註
能夠考慮按照組件的名稱的縮寫做爲前綴,(同一個xml文件中ID名稱不能重複)如:組件簡寫(大寫字母縮寫)_業務名稱
TextView的組件:tv_pay_money
Button的組件:btn_pay_money
EditText的組件:et_user_name
LinerLayout組件:ll_container
2.10.5 舉例
如:好比一個textview組件,可點擊用於支付的按鈕,則能夠把ID定義爲: tv_pay_money;
3 註釋規範
3.1 類註釋
在類、接口定義以前當對其進行註釋,包括類、接口的目的、做用、功能、繼承於何種父類,實現的接口、實現的算法、使用方法、示例程序等。
/**
* author:做者
* time:時間
* desc:描述
*/
3.2 方法註釋
方法註釋的模板:
/**
* desc:描述
* @param 參數名 參數描述
* @param 參數名2 參數描述
* @return 返回值類型說明
* @throws Exception 異常說明
*/
3.3 類成員變量和常量註釋
成員變量和常量須要使用以下注釋的形式,註釋位於變量的上側;
/**
*
**/
3.4 內部邏輯註釋
內部邏輯註釋模板:
//支付成功
if (response.getRet() == 0) {
Toast.makeText(H5Activity.this, "支付成功", Toast.LENGTH_LONG).show();
goToNext(response);
}
//支付失敗
else if (response.getRet() == -1) {
Toast.makeText(H5Activity.this, "支付失敗", Toast.LENGTH_LONG).show();
//刷新當前頁面
reflush(currentUrl);
}
4 代碼順序
4.1 代碼順序
在一個典型的Activity中代碼的順序以下:
/**
* author:sh
* desc:該class的做用
* time:yyyy-MM-dd
**/
public class ClassName {
//(1) 成員變量集合
//(2) 回調方法集合
若該類爲activity,則:onCreate、**、onDestory;
若該類爲Fragment、則:onCreateView、**、onDestory;
//(3) 其餘方法集合
}
5 代碼風格
5.1 大括號換行
左大括號不換行,右大括號換行;
class MyClass {
int func() {
if (something) {
// ...
} else if (somethingElse) {
// ...
} else {
// ...
}
}
}
5.2 小括號空格
if (condition) {
body();
} // 推薦
5.3 縮進
4 個空格做爲縮進排版的一個單位,不使用製表符 tab。
8 個空格做爲換行後的縮進,包括函數調用和賦值。
Instrument i =
someLongexpression_r(that, NotFit, on, one, line); // 推薦
5.4 每一行的長度
儘可能避免一行的長度超過 100 個字符。
例外:若是註釋行包含了超過 100 個字符的命令示例或者 url 文字,爲了便於剪切和複製,其長度能夠超過 100 個字符。
例外:import 行能夠超過限制,由於不多有人會去閱讀它。這也簡化了編程工具的寫入操做。
5.5 每次聲明一個變量
推薦一行一個聲明,由於這樣以利於寫註釋;
int level; // indentation level
int size; // size of table
5.6 if-else語句
if-else語句應該具備以下格式:
if (condition) {
statements;
}
if (condition) {
statements;
} else {
statements;
}
if (condition) {
statements;
} else if (condition) {
statements;
} else{
statements;
}
注意:if語句老是用」{「和」}「括起來,避免使用以下容易引發錯誤的格式:
if (condition) // 避免
statement;
5.7 for語句
一個for語句應該具備以下格式:
for (initialization; condition; update) {
statements;
}
當在for語句的初始化或更新子句中使用逗號時,避免因使用三個以上變量,而致使複雜度提升。
若須要,能夠在for循環以前(爲初始化子句)或for循環末尾(爲更新子句)使用單獨的語句。
5.8 while語句
一個while語句應該具備以下格式:
while (condition) {
statements;
}
5.9 do-while語句
do {
statements;
} while (condition);
5.10 switch語句
一個switch語句應該具備以下格式:
switch (condition) {
case ABC:
statements;
/* falls through */
case DEF:
statements;
break;
case XYZ:
statements;
break;
default:
statements;
break;
}
每當一個case順着往下執行時(由於沒有break語句),一般應在break語句的位置添加註釋。
6 異常規範
6.1 異常名稱
定義異常的時候,異常的後綴名稱以Exception結尾,及**Exception;
6.2 異常描述
儘可能英文描述,簡單明瞭;
6.3 異常格式
一個try-catch語句應該具備以下格式:
try {
statements;
} catch (ExceptionClass e) {
statements;
}
try {
statements;
} catch (ExceptionClass e) {
statements;
} finally {
statements;
}
7 其餘規範
7.1 源文件的函數小於2K
通常來講源文件的行數不能大於2K行,過多的話能夠考慮拆分功能,拆分函數等;
7.2 使用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 註釋是「未來要作某事」的格式)。
7.3 使用自定義LOG
在系統中須要打印LOG的時候,儘可能使用自定義的LOG,自定義的LOG在開發環境的時候會打印日誌,正式環境的時候不會打印日誌。
7.4 使用自定義TAG
在系統打印LOG的時候,使用TAG儘可能使用tab,贊成的TAG標誌。