Android 開發規範

1.AS規範

  1. 儘可能使用最新的穩定的IDE進行開發;
  2. 編碼格式統一爲 UTF-8;
  3. 刪除多餘的 import,減小警告出現,可利用 AS 的 Optimize Imports(Settings -> Keymap -> Optimize Imports)快捷鍵;

2.命名規範

代碼中的命名嚴禁使用拼音與英文混合的方式,更不容許直接使用中文的方式。java

2.1 包

2.1.1 包名

  1. 包名必須是所有小寫,連續的單詞只是簡單地鏈接起來,不使用下劃線,採用反域名命名規則。
  2. 一級包名爲頂級域名,一般爲 comedu
  3. 二級包名爲公司名,如 denglin
  4. 三級包名爲應用名,如 rubbish

2.1.2 包名劃分

  1. 推薦採用PBF(按照功能分包Package By Feature)不建議使用PBL(按層分包 Package By Layer)
  2. 按照功能分包具體能夠這樣作:
com
└── domain
    └── app
        ├── App.java 定義 Application 類
        ├── Config.java 定義配置數據(常量)
        ├── Activity  
        │   ├── HomeActivity 
        │   ├── LoginActivity 
        │   ├── AboutActivity 
        ├── base 基礎組件
        ├── custom_view 自定義視圖
        ├── data 數據處理
        │   ├── DataManager.java 數據管理器
        |   ├── Aes.java Aes數據加密解密
        │   ├── local 來源於本地的數據,好比 SP,Database,File
        │   ├── model 定義 model(數據結構以及 getter/setter、compareTo、equals 等等,不含複雜操做)
        │   └── remote 來源於遠端的數據
        ├── feature 功能
        │   ├── feature0 功能 0(搜索垃圾分類)
        │   │   ├── feature0Fragment.java
        │   │   ├── xxAdapter.java
        │   │   └── ... 其餘 class
        |   ├── feature1 功能 1(獲取垃圾搜索熱點)
        │   │   ├── feature1Fragment.java
        │   │   ├── xxAdapter.java
        │   │   └── ... 其餘 class
        |   ├── feature2 功能 2(app啓動時同步最新垃圾分類數據)
        │   │   ├── feature1Fragment.java
        │   │   ├── xxAdapter.java
        │   │   └── ... 其餘 class
        │   └──....其餘功能
        ├── injection 依賴注入
        ├── util 工具類(例如網絡請求,數據上傳)
        └── widget 小部件
複製代碼

2.2 類

2.2.1 類名

  • 使用駝峯命名 例如: LoginActivity
  • 儘可能不使用縮寫

常見類命名格式數據庫

描述 例如
Activity Activity 爲後綴標識 主頁面類 HomeActivity
Adapter Adapter 爲後綴標識 新聞詳情適配器 NewsDetailAdapter
解析類 Parser 爲後綴標識 首頁解析類 HomePosterParser
工具方法類 UtilsManager 爲後綴標識 打印工具類:PrinterUtils
數據庫類 DBHelper 後綴標識 新聞數據庫:NewsDBHelper
Service Service 爲後綴標識 時間服務 TimeService
BroadcastReceiver Receiver 爲後綴標識 推送接收 JPushReceiver
ContentProvider 以 Provider 爲後綴標識 ShareProvider
自定義的共享基礎類 Base 開頭 BaseActivity, BaseFragment

2.2.2 接口

  • 使用駝峯命名 多以able或者ible結尾 例如:interface Runnable
  • 若是項目採用MVP設計,全部 ModleViewPresenter 的接口都是以 I 爲前綴,不加後綴,其餘的接口採用上述命名規則。

2.3 方法名

  • 方法名以 lowerCamelCase 風格編寫。
  • 方法名一般是動詞或動詞短語。

常見方法命名數組

方法 說明
initXX() 初始化相關方法,例:初始化佈局 initView()
isXX() checkXX() 方法返回boolean類型
getXXX() 返回某個值的方法
setXXX() 設置某個屬性值
handleXXX() processXXX() 對數據進行處理的方法
displayXXX() showXX() 顯示提示框或者消息提示
updateXX() 更新數據
saveXXX() 保存數據
clearXXX() 清除數據
removeXXX() 移除數據或者視圖等,如:removeView()
drawXXX() 繪製數據或者效果相關等

2.4 常量名

  • 常量名命名所有字母大寫, 用下劃線分割單詞。 例如: CONSTANT_CAS
  • 常量名都是一個靜態 final 字段,但不是全部靜態 final 字段都是常量。
static final int VERSION = 1;
static final String VERSION_NAME "hello world";
複製代碼

2.5 很是量字段名

很是量字段名以 lowerCamelCase 風格的基礎上改造爲以下風格: 基本結構爲 scopeVariableNameTypebash

2.5.1 scope (範圍)

  • 非公有,非靜態字段命名爲 m 開頭。
  • 靜態字段命名爲 s 開頭。
  • 其餘字段以小寫字母開頭。

例如:網絡

public class MyClass {
    public int publicField;
    private static MyClass sSingleton;
    int mPackagePrivate;
    private int mPrivate;
    protected int mProtected;
}
複製代碼

使用 1 個字符前綴來表示做用範圍,1 個字符的前綴必須小寫,前綴後面是由表意性強的一個單詞或多個單詞組成的名字,並且每一個單詞的首寫字母大寫,其它字母小寫,這樣保證了對變量名可以進行正確的斷句。數據結構

2.5.2 控件類型

爲了不控件和普通成員變量混淆以及更好地表達意思,全部用來表達控件的成員變量統一加上控件縮寫做爲前綴app

UI控件縮寫表dom

名稱 縮寫
Button btn
CheckBox cb
EditText et
FrameLayout fl
GridView gv
ImageButton ib
ImageView iv
LinearLayout ll
ListView lv
ProgressBar pb
RadioButtion rb
RecyclerView rv
RelativeLayout rl
ScrollView sv
SeekBar sb
Spinner spn
TextView tv
ToggleButton tb
VideoView vv
WebView wv

2.6 變量名

變量名中可能會出現量詞,咱們須要建立統一的量詞,他們更容易理解,也更容易搜索。 例如: mFirstBookmPreBookcurBookide

量詞列表 量詞後綴說明
First 一組變量中的第一個
Last 一組變量中的最後一個
Next 一組變量中的下一個
Pre 一組變量中的上一個
Cur 一組變量中的當前變量

3. 代碼規範

3.1使用標準大括號樣式

左大括號不單獨佔一行,與其前面的代碼位於同一行:函數

class MyClass {
    int func() {
        if (something) {
            // ...
        } else if (somethingElse) {
            // ...
        } else {
            // ...
        }
    }
}
複製代碼

須要在條件語句周圍添加大括號。例外狀況整個條件語句適合放在同一行,那麼能夠將其所有放在一行上。例如,咱們接受一下樣式:

if (condition) {
    body();
}
複製代碼

也能夠接受一下樣式:

if (condition) body();
複製代碼

但不接受一下樣式:

if (condition)
    body(); 
複製代碼

3.2 類成員的順序

推薦使用以下的排序順序:

  1. 常量
  2. 字段
  3. 構造函數
  4. 重寫函數和回調
  5. 公有函數
  6. 私有函數
  7. 內部類或接口 例如:
public class MainActivity extends Activity {

    private static final String TAG = MainActivity.class.getSimpleName();

    private String mTitle;
    private TextView mTextViewTitle;

    @Override
    public void onCreate() {
        ...
    }

    public void setTitle(String title) {
    	mTitle = title;
    }

    private void setUpView() {
        ...
    }

    static class AnInnerClass {

    }
}
複製代碼

若是類繼承於Android組件例如:Activity,那麼把重寫函數按照他們的生命週期進行排序是一個很是好的習慣。例如:

public class MainActivity extends Activity {
    //Order matches Activity lifecycle
    @Override
    public void onCreate() {}

    @Override
    public void onResume() {}

    @Override
    public void onPause() {}

    @Override
    public void onDestroy() {}
}
複製代碼

3.3 函數參數的排序

在Android開發過程當中, Context 在函數參數中是再常見不過的了,咱們最好把 Context 做爲函數的第一個參數。

相反,咱們回調接口應該做爲其最後一個參數。

例如:

// Context always goes first
public User loadUser(Context context, int userId);

// Callbacks always go last
public void loadUserAsync(Context context, int userId, UserCallback callback);
複製代碼

3.4 字符串常量的命名和值

Android SDK中的不少類都用到了鍵值對函數,好比 SharedPreferencesBundleIntent ,因此,即使是一個小應用,咱們最終也不得不編寫大量的字符串常量。

當咱們用到這些類時,必須將他們的將定義爲 static final 字段,而且遵循如下指示做爲前綴。

字段名前綴
SharedPreferences PREF_
Bundle BUNDLE_
Fragment Arguments ARGUMENT_
Intent Extra EXTRA_
Intent Action ACTION_

說明:雖然 Fragment.getArguments() 獲得的也是 Bundle ,但由於這是 Bundle 的經常使用用法,因此特地爲此定義一個不一樣的前綴。

例如:

// 注意:字段的值與名稱相同以免重複問題
static final String PREF_EMAIL = "PREF_EMAIL";
static final String BUNDLE_AGE = "BUNDLE_AGE";
static final String ARGUMENT_USER_ID = "ARGUMENT_USER_ID";

// 與意圖相關的項使用完整的包名做爲值的前綴
static final String EXTRA_SURNAME = "com.myapp.extras.EXTRA_SURNAME";
static final String ACTION_OPEN_USER = "com.myapp.action.ACTION_OPEN_USER";
複製代碼

3.5 Activities 和 Fragments 的傳參

當 Activity 或 Fragment 傳遞數據經過 Intent 或 Bundle 時,不一樣值的鍵須遵循上一條所說起到的。

當 Activity 或 Fragment 啓動須要傳遞參數時,那麼它須要提供一個 public static 的函數來幫助啓動或建立它。

這方面,AS 已幫你寫好了相關的 Live Templates,啓動相關 Activity 的只須要在其內部輸入 starter 便可生成它的啓動器,以下所示:

public static void start(Context context, User user) {
      Intent starter = new Intent(context, MainActivity.class);
      starter.putParcelableExtra(EXTRA_USER, user);
      context.startActivity(starter);
}
複製代碼

同理,啓動相關 Fragment 在其內部輸入 newInstance 便可,以下所示:

public static MainFragment newInstance(User user) {
      Bundle args = new Bundle();
      args.putParcelable(ARGUMENT_USER, user);
      MainFragment fragment = new MainFragment();
      fragment.setArguments(args);
      return fragment;
}
複製代碼

4. 行長限制

4.1 換行策略

  1. 除賦值操做以外,咱們把換行符放在操做符以前,例如:
int longName = anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne
        + theFinalOne;
複製代碼
  1. 賦值操做符的換行咱們放在其後,例如:
int longName =
        anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne + theFinalOne;
複製代碼

4.2 函數鏈的換行

當同一行中調用多個函數時,對每一個函數的調用都應該在行的一行中,咱們把換行符插入在 . 以前。

例如:

Picasso.with(context).load("https://blankj.com/images/avatar.jpg").into(ivAvatar);
複製代碼

應該使用以下規則:

Picasso.with(context)
        .load("https://blankj.com/images/avatar.jpg")
        .into(ivAvatar);
複製代碼

4.3 多參數的換行

當一個方法有不少參數或者參數很長的時候,咱們應該在每一個 , 後面進行換行。 好比:

loadPicture(context, "https://blankj.com/images/avatar.jpg", ivAvatar, "Avatar of the user", clickListener);
複製代碼

應該使用以下規則:

loadPicture(context,
        "https://blankj.com/images/avatar.jpg",
        ivAvatar,
        "Avatar of the user",
        clickListener);
複製代碼

4.4 RxJava 鏈式換行

RxJava 的每一個操做符都須要換新行,而且把換行符插入在 . 以前。

例如:

public Observable<Location> syncLocations() {
    return mDatabaseHelper.getAllLocations()
            .concatMap(new Func1<Location, Observable<? extends Location>>() {
                @Override
                 public Observable<? extends Location> call(Location location) {
                     return mRetrofitService.getLocation(location.id);
                 }
            })
            .retry(new Func2<Integer, Throwable, Boolean>() {
                 @Override
                 public Boolean call(Integer numRetries, Throwable throwable) {
                     return throwable instanceof RetrofitError;
                 }
            });
}
複製代碼

5.資源文件規範

6.註釋規範

6.1類註釋

每一個類完成後應該有做者姓名和聯繫方式的註解,對本身的代碼負責。 例如:

/**
 * author : Blankj
 * time   : 2019/07/13
 * desc   : xxxx 描述
 * version: 1.0
 */
public class WelcomeActivity {
    ...
}

複製代碼

具體能夠在AS在那個本身配置,進入 Settings -> Editor -> File and Code Templates -> Includes -> File Header,輸入

/**
 * author : ${USER}
 * time   : ${YEAR}/${MONTH}/${DAY}
 * desc   : 
 * version: 1.0
 */
複製代碼

這樣可在每次新建類的時候自動加上該頭註釋。

6.2方法註釋

每個成員方法(包括自定義成員方法、覆蓋方法、屬性方法)的方法頭都必須作方法頭註釋,在方法前一行輸入 /** + 回車 或者設置 Fix doc comment(Settings -> Keymap -> Fix doc comment)快捷鍵,AS 便會幫你生成模板,咱們只須要補全參數便可,以下所示。

/**
 * bitmap 轉 byteArr
 *
 * @param bitmap bitmap 對象
 * @param format 格式
 * @return 字節數組
 */
public static byte[] bitmap2Bytes(Bitmap bitmap, CompressFormat format) {
    if (bitmap == null) return null;
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(format, 100, baos);
    return baos.toByteArray();
}
複製代碼

6.3塊註釋

塊註釋與其周圍的代碼在同一縮進級別。它們能夠是 /* ... */ 風格,也能夠是 // ... 風格(// 後最好帶一個空格)。對於多行的 /* ... */ 註釋,後續行必須從 * 開始, 而且與前一行的 * 對齊。如下示例註釋都是 OK 的。

/*
 * This is
 * okay.
 */

// And so
// is this.

/* Or you can
* even do this. */
複製代碼

6.4其餘註釋

AS 已幫你集成了一些註釋模板,咱們只須要直接使用便可,在代碼中輸入 todo、fixme 等這些註釋模板,回車後便會出現以下注釋。

// TODO: 17/3/14 須要實現,但目前還未實現的功能的說明
// FIXME: 17/3/14 須要修正,甚至代碼是錯誤的,不能工做,須要修復的說明
複製代碼
相關文章
相關標籤/搜索