Android編程規(guī)范不完全指南

參考資料:我總結(jié)的Android編程規(guī)范

1. 命名規(guī)則

1.1 類名奈偏,接口名:

以大寫開頭淮捆,如果一個類的類名由多個單詞組成郁油,所有單詞的首字母必須大寫,單詞盡量寫全稱攀痊,不要簡寫桐腌,除非約定俗成的名字,例如:URL苟径,RTMP案站,RTSP 這些廣泛使用的專有名詞,可以全部大寫涩笤,也可以首字母大寫嚼吞。

例如:HttpRequest盒件,CourseActivity

1.2 局部變量蹬碧,類的成員變量,類的成員函數(shù)炒刁,函數(shù)參數(shù):

以小寫字母開頭其他的單詞首字母大寫恩沽,變量名不建議使用下劃線分隔單詞,建議使用駝峰命名法翔始,Android 的系統(tǒng)類都采用此方法罗心。

例如:toString()onCreateView(Bundle saveInstanceState)

1.3 靜態(tài)常量:

常量單詞全部大寫城瞎,所以單詞之間使用下劃線分隔渤闷。

例如:WHAT_EMPTY_CONTENT

1.4 控件變量的命令,控件的ID命名:

建議:xml 布局文件中的控件的id的命令與*.java的代碼文件中的空間對象的命名保持一致脖镀。

class MyActivity extends Activity {
    TextView txtUserName;
    ...
    void onCreate(Bundle saveInstanceState) {
        txtUserName = (TextView) findViewById(R.id.txtUserName);
    }
}

1.5 常用控件以及類對象命名的規(guī)范說明:

類名 變量名 類名 變量名
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

1.6 資源命名:

  1. layout資源文件的命名(全部小寫飒箭,下劃線分隔):
    • activity資源文件:activity_description1_description2.xml
    • fragment資源文件:fragment_description1_description2.xml
    • listview列表項(xiàng)資源文件:list_item_description1_description2.xml
    • 可復(fù)用(被include)的組件資源文件:control_description1_description2.xml
    • drawable資源:controlName_description1_description2_selector.xml
      • controlName表示該資源要用在什么類型的控件上,例如:如果是按鈕的圖片切換則應(yīng)該命名為button_bg_sendmessage_selector.xml
      • selector表示該資源的形式蜒灰,例如還有shape
  2. 圖片資源的命名:同上
  3. 顏色值的命名:color_descriptioncolor為前綴弦蹂,全部小寫,下劃線分割强窖。
    description既可以是該顏色使用的功能描述凸椿,也可以是該顏色的英文描述,也可以是具體的顏色值翅溺,例如:
<color name="color_white">#ffffff</color>
<color name="color_grey_ccc">#cccccc</color>
<color name="color_grey_ddd">#dddddd</color>

因?yàn)間rey可能有很多的等級脑漫,有時候需要不同等級的灰色髓抑,沒有那么多英文名可以區(qū)分,所以名字中可以直接使用顏色值

<color name="color_button_pressed">#4c4c4c</color>

根據(jù)功能定義description优幸,表示該顏色用于按鈕按下

注:不允許出現(xiàn)毫無意義的命名启昧,例如 textview1, textview2

2. 關(guān)于字面常量

代碼中不允許出現(xiàn)直接硬編碼的字面常量,如果是控件上顯示的文本劈伴,必須放在string.xml資源文件中密末。如果是代碼中用到的常量字符串,必須定義成public static final String類型的常量值跛璧,在代碼中使用該定義的常量值严里。

這樣做的好處是以后需要修改該常量值,只需要修改一個地方追城。如果是硬編碼在代碼中則需要修改所有使用它的地方刹碾,而且拷貝容易出錯。

Activity之間傳遞參數(shù)的時候座柱,intent.putExtrakey值也要符合命名規(guī)范迷帜,并且統(tǒng)一定義為靜態(tài)常量,不能直接硬編碼在代碼中色洞,否則想要修改的時候非常麻煩戏锹。某一個Activity在被啟動的時候需要接受參數(shù),那么這些參數(shù)的key定義就應(yīng)該放在該Activity中火诸。

3. JSON解析

Android中調(diào)用服務(wù)器端的接口一般返回的是JSON數(shù)據(jù)锦针,在解析JSON的時候,無論是使用原始的手工解析方式置蜀,還是使用javabean的解析方式奈搜,解析出來的結(jié)果在使用的時候必須都進(jìn)行判空處理。不允許因?yàn)榉?wù)端的json出問題盯荤,導(dǎo)致app在解析json的時候出現(xiàn)崩潰馋吗。

4. 類成員初始化

所有類的成員變量一定要賦初始值,不允許只定義秋秤,不賦值宏粤。

5. Int類型常量

函數(shù)返回的時候,如果返回的int類型的數(shù)據(jù)并不是真實(shí)的實(shí)用的數(shù)據(jù)值(例如表示寬度航缀、高度商架、大小等值),僅僅代表函數(shù)執(zhí)行成功芥玉、失敗蛇摸、異常的狀態(tài)值,并且這些值是有限的幾個值灿巧,必須要將這些值使用靜態(tài)常量描述赶袄,或者使用枚舉類型揽涮,例如:

int GetJsonString()

該函數(shù)返回-1表示獲取解析JSON數(shù)據(jù)異常,返回0表示成功饿肺,返回1表示網(wǎng)絡(luò)連接異常蒋困,返回2表示JSON內(nèi)容中的數(shù)據(jù)部分為空。

那么在函數(shù)內(nèi)部的代碼里不要直接使用這些字面值敬辣,這些字面值對于程序員來說是毫無意義的雪标,代碼可閱讀性很差,建議做成下面的模式:

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;

使用這些符號常量值代替字面值的好處是溉跃,符號常量值是由大寫的英文單詞組成村刨,是有意義的,可以幫助程序員更好的理解函數(shù)返回值的意義撰茎,而且符號常量值對應(yīng)的具體的賦值在后期也是很方便修改的嵌牺。

6. Activity 接受參數(shù)與模塊化

如果一個Activity可能在多個地方被打開,或者一個Fragment可能在多個地方被用到龄糊。那么在設(shè)計(jì)該ActivityFragment的時候一定要考慮低耦合逆粹,對外提供統(tǒng)一的參數(shù)接口,啟動Activity的過程封裝在該Activity類的靜態(tài)成員方法里炫惩。

類似如下:

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);
    }
}

參數(shù)的傳遞最好是封裝在一個Model實(shí)體中僻弹,避免使用Map這種方式進(jìn)行參數(shù)傳遞。建議該實(shí)體類實(shí)現(xiàn)為對應(yīng)的Activity的靜態(tài)可序列化的內(nèi)部類诡必。

7. Android Studio 工程目錄組織

Android Studio 中的項(xiàng)目的包結(jié)構(gòu)應(yīng)該根據(jù)工程各個部分的功能來組織奢方。

8. Handler 的封裝

每個Activity里面幾乎都會定義一個Handler內(nèi)部類搔扁,但是很多Activity里面的Handler都使用了重復(fù)的消息類型爸舒,這里面是有冗余代碼的,所以應(yīng)該把這些Activity都是用到的Handler類的消息部分稿蹲,提取成一個公共的Handler類扭勉。

然后在各個Activity里面使用繼承的方式,來提供該Activity特有的Handler消息類型的Handler類實(shí)現(xiàn)苛聘。

另外Handler發(fā)送消息應(yīng)該使用Handler類的成員函數(shù)涂炎,不應(yīng)該直接使用handler.obtainMessage(xxx).sendToTarget();這種原始的發(fā)送消息的方式,這樣不利于降低耦合设哗,這種細(xì)節(jié)應(yīng)該隱藏在Handler類的里面唱捣。

Handler的消息類型應(yīng)該定義為Handler類里面的靜態(tài)常量,而該常量不應(yīng)是public的网梢,對外部不可見震缭。也就是說使用handler對象發(fā)送消息的細(xì)節(jié)不應(yīng)該暴露給外部。

9. List 數(shù)據(jù)更新

封裝ListView的數(shù)據(jù)更新战虏,在handlerMessage中更新數(shù)據(jù)拣宰,避免出現(xiàn)java.lang.IllegalStateException問題

10. Activity 與 Fragment 之間傳遞參數(shù)

ActivityFragment的數(shù)據(jù)傳遞采用interface的方式党涕,也就是代理的方式,這樣可以降低耦合巡社,有利于Fragment的復(fù)用:
在你的fragment中定義一個接口:

public interface OnDataPass {
    public void onDataPass(String data);
}

然后膛堤,在你的fragmentonAttach(Activity a)方法中實(shí)例化一個OnDataPass

OnDataPass dataPasser;

@Override
public void onAttach(Activity a) {
    super.onAttach(a);
    dataPasser = (OnDataPass) a;
}

在你的fragment中,當(dāng)你想處理傳遞的數(shù)據(jù)時晌该,只需要調(diào)用dataPasseronDataPass方法即可:

public void passData(String data) {
    dataPasser.onDataPass(data);
}

最后肥荔,在你的容器activity中實(shí)現(xiàn)OnDataPass接口:

public class MyActivity extends Activity implements OnDataPass {
    ...
    @Override
    public void onDataPass(String data) {
        Log.d("LOG", "Hello " + data);
    }
}

11. 網(wǎng)絡(luò)請求數(shù)據(jù)模塊化

一般在Activity中我們通過網(wǎng)絡(luò)請求服務(wù)端的接口獲得數(shù)據(jù),這個過程一般是在一個線程中做的朝群,獲取到數(shù)據(jù)之后次企,再通過Activity中的handler發(fā)送消息來通知Activity更新數(shù)據(jù)。

該負(fù)責(zé)獲取數(shù)據(jù)的線程類潜圃,我們一般都實(shí)現(xiàn)為一個Activity的內(nèi)部類缸棵,該類可以直接訪問Activity的成員變量,例如handler谭期,數(shù)據(jù)列表對象等堵第。但是這樣不利于該數(shù)據(jù)獲取線程的復(fù)用。如果另一個Activity里面也需要獲取相同的數(shù)據(jù)隧出,那么這個功能是不能復(fù)用的踏志。

所以這個負(fù)責(zé)數(shù)據(jù)請求的線程類,不應(yīng)該與具體的HandlerActivity聯(lián)系過于緊密胀瞪。應(yīng)該定義為一個靜態(tài)類针余,handler應(yīng)該作為參數(shù)傳遞進(jìn)來,而不是直接訪問外部類的成員變量凄诞。

12. 封裝 Log 功能

Log功能應(yīng)該封裝成為自動將當(dāng)前所在類的類名變成log輸出的TAG參數(shù)圆雁,發(fā)布的app最好是能循環(huán)寫日志文件到系統(tǒng)存儲中,并且日志文件應(yīng)該使用反復(fù)覆蓋的方式重復(fù)利用帆谍。

下面僅僅是一個不完善的例子:

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(this, "Hello Log");

打印結(jié)果

V/myapp MainActivity: Hello Log

13. 版本控制

使用自動化版本管理伪朽,自動生成版本號,使應(yīng)用程序的版本與版本庫上保持一致汛蝙。

使用hg替換工程目錄下的app目錄下的build.gradle文件即可烈涮,如果AndroidManifest.xml里面也有版本號的設(shè)置,AndroidStudio還是以build.gradle為準(zhǔn)窖剑。不應(yīng)該在每次發(fā)布的時候坚洽,在AndroidStudio的工程設(shè)置里面手工修改版本號。

14. 為程序添加全局異常捕獲

應(yīng)該為app添加全局異常捕獲西土,app中總會有一些我們未捕獲的異常讶舰,一旦用戶使用過程中遇到這樣的異常,程序就會崩潰,我們應(yīng)該檢測該類未捕獲的異常信息绘雁,程序崩潰的時候通過寫文件日志橡疼,或者發(fā)送郵件的方式獲得異常信息,以便解決bug庐舟。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末欣除,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子挪略,更是在濱河造成了極大的恐慌历帚,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件杠娱,死亡現(xiàn)場離奇詭異挽牢,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)摊求,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門禽拔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人室叉,你說我怎么就攤上這事睹栖。” “怎么了茧痕?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵野来,是天一觀的道長。 經(jīng)常有香客問我踪旷,道長曼氛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任令野,我火速辦了婚禮舀患,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘彩掐。我一直安慰自己构舟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布堵幽。 她就那樣靜靜地躺著,像睡著了一般弹澎。 火紅的嫁衣襯著肌膚如雪朴下。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天苦蒿,我揣著相機(jī)與錄音殴胧,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛团滥,可吹牛的內(nèi)容都是我干的竿屹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼灸姊,長吁一口氣:“原來是場噩夢啊……” “哼拱燃!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起力惯,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤碗誉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后父晶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哮缺,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年甲喝,在試婚紗的時候發(fā)現(xiàn)自己被綠了尝苇。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡埠胖,死狀恐怖茎匠,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情押袍,我是刑警寧澤诵冒,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站谊惭,受9級特大地震影響汽馋,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜圈盔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一豹芯、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧驱敲,春花似錦铁蹈、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至娩梨,卻和暖如春沿腰,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狈定。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工颂龙, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留习蓬,地道東北人。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓措嵌,卻偏偏與公主長得像躲叼,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子企巢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容