Android編碼規範

0x00 命名規範

基本原則:遵循駝峯命名規則,名字能準確描述表達的含義,好的命名可以省去代碼註釋。

1 常量命名

所有單詞大寫,單詞間以”_“分隔

2 變量命名

駝峯命名。成員變量以m開頭;靜態變量以s開頭

3 方法命名

駝峯命名。

4 接口

首字母大寫,駝峯命名,使用名詞。帶I前綴,或able,ible,er等後綴,如IManager,OnClickListener

5 類

首字母大寫,駝峯命名,使用名詞。

6 包

所有單詞小寫,只能包含a-z字母,或有含義的阿拉伯數字如4代替for,2代替to

7 資源文件

(1)佈局文件

Type Format
Activity activity_
Fragment fragment_
Dialog dialog_
PopupWindow popup_
Menu menu_
Adapter layout_item_

(2)圖片

Suffix Meaning
bg_xxx 背景圖片
btn_xxx 按鈕
ic_xxx 單個圖標
bg _ 描述 _ 狀態 控件上的不同狀態
btn _ 描述 _ 狀態 按鈕上的不同狀態
chx _ 描述 _ 狀態 選擇框,一般2態或4態

0x01 編碼順序

基本原則

  • 一個類的代碼結構從上到下依次爲,packageimport常量/變量塊方法塊
  • 總體上來說,要按照先 public, 後 protected, 最後 private, 方法的排布也應該有一個邏輯的先後順序,由重到輕。

1 import

類/包導入順序爲:AndroidThird PartyJava/Javax。且這三組之間空一行,組內按a-z排列順序

2 常量/變量

順序爲:(1)常量、靜態變量、成員變量(2)public,protected,private

3 方法

對於普通類,方法順序爲:先publicprotectedprivate

對於組件類,方法順序爲:構造方法生命週期方法public方法protected方法private方法

0x02 通用規則

1 基礎

  • 不要直接跨業務模塊調用方法,一個模塊提供一個對外類
  • 禁止將整個類格式化
  • 每個類長度不超過1000行
  • 一行最多隻能寫一條語句,不允許一行定義多個變量或執行多條語句
  • 一個方法只做一件事情,方法體不能太長,且不能傳入太多參數,一般5個以內,暫定不超過8個
  • 每行代碼不超過100個字符,超過的需要使用縮進換行
  • 嵌套層數不應超過3層
  • 代碼中禁止使用硬編碼,把一些數字或字符串定義成常量
  • 用4個空格替代TAB符
  • 恰當使用TODO:FIXME:
  • if/else,switch,for,while

2 異常處理

基本原則Don't Ignore Exceptions. Don't Catch Generic Exception.

  • 異常可以拋給上層處理、或在catch塊中拋給上層處理、或直接在try/catch中打印並做出合理處理,如果catch塊不做處理需要註明原因
  • 不要直接捕獲通用Exception基類,對於已知的每種異常,catch中需要具體列出來,並對每種異常做出相應處理,形如try/catch(JSONException e)/catch(Exception e)/finally,先catch已知異常再catch通用Exception
  • 在某些情況下,允許直接捕獲Exception基類。如爲了防止在UI或批處理任務中出現錯誤,可以在應用頂層加上try/catch(Exception e),但是需要註明原因

0x03 代碼註釋

對於需要說明的代碼,最好寫註釋說明。

0x04 代碼示例

public class CodingRuler {
    /** 公有的常量註釋 */
    public static final String ACTION_MAIN = "android.intent.action.MAIN";
    /** 私有的常量註釋(同類型的常量可以分塊並緊湊定義) */
    private static final int MSG_AUTH_NONE    = 0;
    private static final int MSG_AUTH_SUCCESS = 1;
    private static final int MSG_AUTH_FAILED  = 2;
    /** 保護的成員變量註釋 */
    protected Object mObject0;
    /** 私有的成員變量 mObject1 註釋(同類型的成員變量可以分塊並緊湊定義) */
    private Object mObject1;
    /** 私有的成員變量 mObject2 註釋 */
    private Object mObject2;
    /** 私有的成員變量 mObject3 註釋 */
    private Object mObject3;
    /**
     * 對於註釋多於一行的,採用這種方式來
     * 定義該變量
     */
    private Object mObject4;
    
    /**
     * 公有方法描述...
     * 
     * @param param1  參數1描述...
     * @param param2  參數2描述...
     * @param paramXX 參數XX描述...
     */
    public void doSomething(int param1, float param2, String paramXX) {
        // TODO  使用TODO來標記代碼,說明標識處有功能代碼待編寫
        // FIXME 使用FIXME來標記代碼,說明標識處代碼需要修正,甚至代碼是
        //       錯誤的,不能工作,需要修復
    }

    /**
     * 保護方法描述...
     */
    @Deprecated
    protected void doSomething() {
        // ...implementation
    }

    /**
     * 私有方法描述...
     * 
     * @param param1  參數1描述...
     * @param param2  參數2描述...
     */
    private void doSomethingInternal(int param1, float param2) {
        // ...implementation        
    }

    /**
     * 條件表達式原則。
     */
    private void conditionFun() {
        boolean condition1 = true;
        boolean condition2 = false;
        boolean condition3 = false;
        boolean condition4 = false;
        boolean condition5 = false;
        boolean condition6 = false;
        // 原則: 1\. 所有 if 語句必須用 {} 包括起來,即便只有一句,禁止使用不帶{}的語句
        //       2\. 在含有多種運算符的表達式中,使用圓括號來避免運算符優先級問題
        //       3\. 判斷條件很多時,請將其它條件換行
        if (condition1) {
            // ...implementation
        }
        if (condition1) {
            // ...implementation
        } else {
            // ...implementation
        }
        if (condition1)          /* 禁止使用不帶{}的語句 */
            condition3 = true;
        if ((condition1 == condition2) 
            || (condition3 == condition4)
            || (condition5 == condition6)) {
        }
    }

    /**
     * Switch語句原則。
     */
    private void switchFun() {
        // 原則: 1\. 請默認寫上 default 語句,保持完整性
        int code = MSG_AUTH_SUCCESS;
        switch (code) {
        case MSG_AUTH_SUCCESS:
            break;
        case MSG_AUTH_FAILED:
            break;
        case MSG_AUTH_NONE:
            /* Falls through */
        default:
            break;
        }
    }

    /**
     * 循環表達式。
     */
    private void circulationFun() {
        // 原則: 1\. 循環中必須有終止循環的條件或語句,避免死循環
        //       2\. 循環要儘可能的短, 把長循環的內容抽取到方法中去
        //       3\. 嵌套層數不應超過3層, 要讓循環清晰可讀
        int array[] = { 1, 2, 3, 4, 5 };
        for (int data : array) {
            // ...implementation
        }
        int length = array.length;
        for (int ix = 0; ix  < length; ix++) {
            // ...implementation
        }
        boolean condition = true;
        while (condition) {
            // ...implementation
        }
        do {
            // ...implementation
        } while (condition);
    }

    /**
     * 異常捕獲原則。
     */
    private void exceptionFun() {
        // 原則: 1\. 捕捉異常是爲了處理它,通常在異常catch塊中輸出異常信息。
        //       2\. 資源釋放的工作,可以放到 finally 塊部分去做。如關閉 Cursor 等。
        try {
            // ...implementation
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
    }

    /**
     * 其它原則(整理中...)。
     */
    private void otherFun() {
        // TODO
    }
}

0x05 參考資料

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