命名規則
1). 類名,介面名:
以大寫開頭,如果一個類的類名由多個單片語成,所有單詞的首字母必須大寫,單詞儘量寫全稱,不要簡寫,除非約定俗成的名字,例如:URL,RTMP,RTSP 這些廣泛使用的專有名詞,可以全部大寫,也可以首字母大寫。
例如 HttpRequest,CourseActivity
2). 區域性變數,類的成員變數,類的成員函式,函式引數:
以小寫字母開頭其他的單詞首字母大寫,變數名不建議使用下劃線分隔單詞,建議使用駝峰命名法,Android的系統類都採用此方法。
例如 toString() onCreateView(Bundle savedInstanceState)
3). 靜態常量:全部大寫,單詞之間使用下劃線分開,常量單詞全部大寫,所以單詞之間使用下劃線分隔。
例如 WHAT_EMPTY_CONTENT
4). 控制元件變數的命名,控制元件的ID命名:
建議:xml佈局檔案中的控制元件的id的命名與*.java的程式碼檔案中的控制元件物件的命名一致。
class MyActivity extends Activity{ TextView txtUserName ; … protected void onCreate(Bundle savedInstanceState) { txtUserName = (TextView) findViewById(R.id.txtUserName); } }
5). 常用控制元件以及類物件命名的規範說明(紅色部分為建議的字首或者字尾):
類名 |
變數名 |
類名 |
變數名 |
TextView |
txtDescription |
ProgressBar |
progressDescription |
Button |
btnDescription |
SeekBar |
seekBarDescription |
ImageButton |
imgBtnDescription |
VideoView |
vvDescription |
ImageView |
imgDescription |
Spinner |
spinDescription |
RadioButton |
rbDescription |
WebView |
webViewDescription |
EditText |
editDescription |
ListView |
listViewDescription |
ScrollView |
scrollDescription |
GridView |
gridDescription |
Handler |
descriptionHandler |
RatingBar |
ratingBarDescription |
PullToRefreshListView |
pullRefreshViewDescription |
Adapter |
descriptionAdapter |
Fragment |
descriptionFragment |
Activity |
descriptionActivity |
List<T> |
descriptionList |
Map<> |
mapDescription |
SlidingMenu |
slidMenuDescription |
ViewPager |
viewPagerDescription |
CheckBox |
chBoxDescription |
View |
viewDescription |
RadioGroup |
rgDescription |
ExpandableListView |
expDescription |
FrameLayout |
frameLayDescription |
SharedPreferences |
spDescription |
LinearLayout |
lineLayDescription |
RelativeLayout |
relativeLayDescription |
startActivityForResult(requestCode) |
REQUEST_CODE_DESCRIPTION |
msg.what |
WHAT_DESCRIPTION |
6). 資源命名:
layout資原始檔的命名(全部小寫,下劃線分隔):
activity的資原始檔:activity_description1_description2.xml
fragment的資原始檔:fragment_description1_description2.xml
listview列表項的資原始檔:list_item_description1_description2.xml
可複用(被include)的元件資原始檔: control_description1_description2.xml
drawable資源: controlName_description1_description2_selector.xml
controlName表示該資源要用在什麼型別的控制元件上面,例如如果是按鈕的圖片切換則
應該這麼定義 button_bg_sendmessage_selector.xml
selector表示該資源的形式,例如還有shape等
圖片資源的名字:同上
顏色值的命名: color_description 以color為字首,全部小寫,下劃線分隔。description既可以是該顏色值使用的功能描述,也可以是該顏色值的英文描述,也可以是具體的顏色值,例如:
<color name="color_white">#ffffff</color>
<color name="color_grey_ccc">#cccccc</color>
<color name="color_grey_ddd">#dddddd</color>
因為grey可能有很多等級,有時候需要不同等級的灰色,沒有那麼多英文名可以區分,所以名字中可以直接使用顏色值
<color name="color_button_pressed">#4c4c4c</color> 根據功能定義description,表示該顏色用於按鈕被按下
注:不允許出現毫無意義的命名,例如textview1,textview2
關於字面常量
程式碼中不允許出現直接硬編碼的字面常量,如果是控制元件上面顯示的文字,必須放在strings.xml資原始檔中。 如果是程式碼中用到常量字串,必須定義成 public static final String型別的常量值,在程式碼中使用該定義的常量值。這樣做的好處是以後需要修改該常量值,只需要修改一個地方。如果是硬編碼在程式碼中則要修改所有使用它的地方,而且拷貝容易出錯。在Activity之間傳遞引數的時候,intent.putExtra 的key值也要命名規範,並且統一定義為靜態常量,不能直接硬編碼在程式碼中,否則想要修改的時候很麻煩。某一個Activity在被啟動的時候需要接受引數,那麼這些引數的key定義就應該放在該Activity中。
JSON解析
Android中呼叫服務端的介面一般返回的是json資料,在解析json的時候,無論是使用原始的手工解析方式,還是使用javabean的解析方式,解析出來的結果在使用的時候必須都進行判空處理。不允許因為服務端的json出問題,導致app在解析json的時候出現崩潰。
類成員初始化
所有類的成員變數一定要賦初始值,不允許只定義,不賦值。
Int型別常量
函式返回的時候,如果返回的int型別的資料並不是真實的實用的資料值(例如表示高度,寬度,大小等值),僅僅表示函式執行成功、失敗、異常的狀態值,並且這些值是有限的幾個值,必須要將這些值使用靜態常量描述,或者使用列舉,例如:
int GetJsonString()
該函式返回-1表示獲取解析json資料異常,返回0表示成功,返回1表示網路連線異常,返回2表示json內容中的資料部分為空。那麼在函式內部的程式碼裡不要直接使用這些字面值,這些字面值對於程式設計師來說是毫無意義的,程式碼可閱讀性很差,建議做成下面的模式:
public static final int RESULT_PARSE_JSON_EXCEPTION = -1;
public static final int RESULT_SUCCESS = 0;
public static final int RESULT_NETWORK_EXCEPTION = 1;
public static final int RESULT_NO_DATA = 2;
使用這些符號常量值代替字面值的好處是,符號常量值是由大寫的英文單片語成,是有意義的,可以幫助程式設計師更好的理解函式返回值的意義,而且符號常量值對應的具體的賦值在後期是很方便修改的。
Activity接受引數與模組化
如果一個Activity可能在多個地方被開啟,或者一個Fragment可能在多個地方被用到。那麼在設計該Activity和Fragment的時候一定要考慮低耦合,對外提供統一的引數介面,啟動Activity的過程封裝在該Activity類的靜態成員方法裡面,類似如下:
class MyActivity extends Activity{ ... public static void startActivity(Context context,Params param){ Intent intent = new Intent(context, MyActivity.class); intent.putExtra("param", param); startActivity(intent); } public static void startActivityForResult(Context context,Params param){ Intent intent = new Intent(context, MyActivity.class); intent.putExtra("param", param); startActivityForResult(intent,REQUEST_CODE); } }
引數的傳遞最好是封裝在一個Model實體類中,避免使用Map這種方式進行引數傳遞。建議該實體類實現為對應的Activity的靜態可序列化的內部類。
AndroidStudio工程目錄組織
AndroidStudio中的專案的包結構應該根據工程各個部分的功能來組織。
Handler的封裝
每一個Activity裡面幾乎都會定義一個Handler內部類,但是很多Activity裡面的Handler都使用了重複的訊息型別,這裡面是有冗餘程式碼的,所以應該把這些Activity都使用到的Handler類的訊息部分,提取成一個公用的Handler類。然後在各個Activity裡面使用繼承的方式,來提供該Activity特有的Handler訊息型別的Handler類實現。
另外Handler傳送訊息應該使用Handler類的成員函式,不應該直接使用handler.obtainMessage(xxx).sendToTarget();
這種原始的傳送訊息的方式,這樣不利於降低耦合,這種細節應該隱藏在Handler類的裡面。Handler的訊息型別應該定義為Handler類裡面的靜態常量,而該常量不應是public的,對外部不可見。也就是說使用handler物件傳送訊息的細節不應該暴露給外部。
List的資料更新
封裝ListView的資料更新,在handlerMessage中更新資料,避免出現 java.lang.IllegalStateException 問題
Activity與Fragment之間傳遞引數
Activity與Fragment的資料傳遞採用interface的方式,這樣可以降低耦合,有利於Fragment的複用:
網路請求資料模組化
一般在Activity中我們通過網路請求服務端的介面獲得資料,這個過程一般是在一個執行緒中做的,獲取到資料之後,再通過Activity中的handler傳送訊息來通知Activity更新資料。該負責獲取資料的執行緒類,我們一般都實現為一個Activity的內部類,該類可以直接訪問Activity的成員變數,例如handler,資料列表物件等。但是這樣不利於該資料獲取執行緒的複用。如果另一個Activity裡面也需要獲取相同的資料,那麼這個功能是不能複用的,所以這個負責資料請求的執行緒類,不應該與具體的Handler和Activity聯絡過於緊密。應該定義為一個靜態類,handler應該作為引數傳遞進來,而不是直接訪問外部類的成員變數。
封裝Log功能
Log功能應該封裝成為自動將當前所在類的類名變成log輸出的TAG引數,釋出的app最好是能迴圈寫日誌檔案到系統儲存中,並且日誌檔案應該使用反覆覆蓋的方式重複利用。下面僅僅是一個不完善的例子:
public class MyLog { public static final String TAG = "myapp "; public static void v(Object o,String message) { Log.v(TAG+o.getClass().getSimpleName(),message); } }
使用
MyLog.v(this,"hello log");
列印結果
V/myapp MainActivity﹕ hello log
版本控制
使用自動化版本管理,自動生成版本號,使應用程式的版本與版本庫上保持一致。使用hg替換工程目錄下的app目錄下的build.gradle檔案即可,如果manifest裡面也有版本號的設定,AndroidStudio還是以build.gradle為準。不應該在每次釋出的時候,在AndroidStudio的工程設定裡面手工修改版本號。
為程式新增全域性異常捕獲
應該為app新增全域性異常捕獲,app中總會有一些我們未捕獲的異常,一旦使用者使用過程中遇到這樣的異常,程式就會崩潰,我們應該檢測該類未捕獲的異常資訊,程式崩潰的時候通過寫檔案日誌,或者傳送郵件的方式獲得異常資訊,以便解決bug。