為了利于項目維護以及規范開發,促進成員之間Code Review的效率,故提出以下開發規范,如有更好建議,歡迎到GitHub提issue,原文地址: 安卓開發規范(updating)
工欲善其事,必先利其器。
.java, .xml等文件后一定要格式化(縮進對齊與AS默認一致即可);
Optimize Imports快捷鍵;
代碼中的命名嚴禁使用拼音與英文混合的方式,更不允許直接使用中文的方式。正確的英文拼寫和語法可以讓閱讀者易于理解,避免歧義。注意,即使純拼音命名方式也要避免采用。但 alibaba, taobao, youku, hangzhou 等國際通用的名稱,可視同英文。
包名全部小寫,連續的單詞只是簡單地連接起來,不使用下劃線。
采用反域名命名規則,全部使用小寫字母。一級包名是頂級域名,通常為com, edu, gov, net, org等,二級包名為公司名,三級包名根據應用進行命名,四級包名為模塊名或層級名。
| 包名 | 此包中包含 |
|---|---|
| com.xx.應用名稱縮寫.activity | 用戶界面中所有的Activity類 |
| com.xx.應用名稱縮寫.fragment | 界面中所有的Fragment類 |
| com.xx.應用名稱縮寫.base | 基礎共享的類 |
| com.xx.應用名稱縮寫.adapter | 頁面用到的Adapter類 (適配器的類) |
| com.xx.應用名稱縮寫.view | 自定義的View類 |
| com.xx.應用名稱縮寫.util | 此包中包含:公共工具方法類(util模塊名) |
| com.xx.應用名稱縮寫.bean | 下面可分:vo、po、dto 此包中包含:JavaBean類 |
| com.xx.應用名稱縮寫.model | 此包中包含:模型類 |
| com.xx.應用名稱縮寫.db | 數據庫操作類 |
| com.xx.應用名稱縮寫.view (或者 com.xx.應用名稱縮寫.widget ) | 自定義的View類等 |
| com.xx.應用名稱縮寫.service | Service服務 |
| com.xx.應用名稱縮寫.receiver | BroadcastReceiver服務 |
| com.xx.應用名稱縮寫.config | 所有的配置相關的類 |
注意:如果項目采用MVP,所有M、V、P抽取出來的接口都放置在相應模塊的i包下,所有的實現都放置在相應模塊的impl下
類名都以UpperCamelCase風格編寫。
類名通常是名詞或名詞短語,接口名稱有時可能是形容詞或形容詞短語。現在還沒有特定的規則或行之有效的約定來命名注解類型。
名詞,采用大駝峰命名法,盡量避免縮寫,除非該縮寫是眾所周知的, 比如HTML,URL,如果類名稱中包含單詞縮寫,則單詞縮寫的每個字母均應大寫。
| 類 | 描述 | 例如 |
|---|---|---|
| Activity 類 | Activity為后綴標識 | 歡迎頁面類WelcomeActivity |
| Adapter類 | Adapter 為后綴標識 | 新聞詳情適配器 NewDetailAdapter |
| 解析類 | Parser為后綴標識 | 首頁解析類HomePosterParser |
| 工具方法類 | Utils或Manager為后綴標識(與系統或第三方的Utils區分)或功能+Utils | 線程池管理類:ThreadPoolManager日志工具類:LogUtils(Logger也可)打印工具類:PrinterUtils |
| 數據庫類 | 以DBHelper后綴標識 | 新聞數據庫:NewDBHelper |
| Service類 | 以Service為后綴標識 | 時間服務TimeService |
| BroadcastReceiver類 | 以Receiver為后綴標識 | 推送接收JPushReceiver |
| ContentProvider類 | 以Provider為后綴標識 | ShareProvider |
| 自定義的共享基礎類 | 以Base開頭 | BaseActivity,BaseFragment |
測試類的命名以它要測試的類的名稱開始,以Test結束。例如:HashTest 或 HashIntegrationTest。
接口(interface):命名規則與類一樣采用大駝峰命名法,多以able或ible結尾,如 interface Runnable , interface Accessible。
注意:如果項目采用MVP,所有Model、View、Presenter的接口都以I為前綴,不加后綴,其他的接口采用上述命名規則。
方法名都以lowerCamelCase風格編寫。
方法名通常是動詞或動詞短語。
| 方法 | 說明 |
|---|---|
| initXX() | 初始化相關方法,使用init為前綴標識,如初始化布局initView() |
| isXX() checkXX() | 方法返回值為boolean型的請使用is或check為前綴標識 |
| getXX() | 返回某個值的方法,使用get為前綴標識 |
| setXX() | 設置某個屬性值 |
| handleXX()/processXX() | 對數據進行處理的方法 |
| displayXX()/showXX() | 彈出提示框和提示信息,使用display/show為前綴標識 |
| updateXX() | 更新數據 |
| saveXX() | 保存數據 |
| resetXX() | 重置數據 |
| clearXX() | 清除數據 |
| removeXX() | 移除數據或者視圖等,如removeView(); |
| drawXX() | 繪制數據或效果相關的,使用draw前綴標識 |
常量名命名模式為CONSTANT_CASE,全部字母大寫,用下劃線分隔單詞。那,到底什么算是一個常量?
每個常量都是一個靜態final字段,但不是所有靜態final字段都是常量。在決定一個字段是否是一個常量時,考慮它是否真的感覺像是一個常量。例如,如果任何一個該實例的觀測狀態是可變的,則它幾乎肯定不會是一個常量。只是永遠不打算改變對象一般是不夠的,它要真的一直不變才能將它示為常量。
// Constants static final int NUMBER = 5; static final ImmutableListNAMES = ImmutableList.of("Ed", "Ann"); static final Joiner COMMA_JOINER = Joiner.on(','); // because Joiner is immutable static final SomeMutableType[] EMPTY_ARRAY = {}; enum SomeEnum { ENUM_CONSTANT } // Not constants static String nonFinal = "non-final"; final String nonStatic = "non-static"; static final SetmutableCollection = new HashSet(); static final ImmutableSetmutableElements = ImmutableSet.of(mutable); static final Logger logger = Logger.getLogger(MyClass.getName()); static final String[] nonEmptyArray = {"these", "can", "change"};
非常量字段名以lowerCamelCase風格的基礎上改造為如下風格:基本結構為scopeVariableNameType。
scope:范圍
非公有,非靜態字段命名以m開頭。
靜態字段命名以s開頭。
公有非靜態字段命名以p開頭。
公有靜態字段(全局變量)命名以g開頭。
例子:
public class MyClass { int mPackagePrivate; private int mPrivate; protected int mProtected; private static MyClass sSingleton; public int pField; public static int gField;
}
使用1字符前綴來表示作用范圍,1個字符的前綴必須小寫,前綴后面是由表意性強的一個單詞或多個單詞組成的名字,而且每個單詞的首寫字母大寫,其它字母小寫,這樣保證了對變量名能夠進行正確的斷句。
Type:類型
考慮到Android中使用很多UI控件,為避免控件和普通成員變量混淆以及更好達意,所有用來表示控件的成員變量統一加上控件縮寫作為后綴(文末附有縮寫表)。
對于普通變量一般不添加類型后綴,如果統一添加類型后綴,請參考文末的縮寫表。
用統一的量詞通過在結尾處放置一個量詞,就可創建更加統一的變量,它們更容易理解,也更容易搜索。
注意:如果項目中使用ButterKnife,則不添加m前綴,以lowerCamelCase風格命名。
例如,請使用 mCustomerStrFirst 和 mCustomerStrLast,而不要使用mFirstCustomerStr和mLastCustomerStr。
| 量詞列表 | 量詞后綴說明 |
|---|---|
| First | 一組變量中的個 |
| Last | 一組變量中的后一個 |
| Next | 一組變量中的下一個變量 |
| Prev | 一組變量中的上一個 |
| Cur | 一組變量中的當前變量 |
說明:
集合添加如下后綴:List、Map、Set 數組添加如下后綴:Arr
注意:所有的VO(值對象)統一采用標準的lowerCamelCase風格編寫,所有的DTO(數據傳輸對象)就按照接口文檔中定義的字段名編寫。
參數名以lowerCamelCase風格編寫。 參數應該避免用單個字符命名。
局部變量名以lowerCamelCase風格編寫,比起其它類型的名稱,局部變量名可以有更為寬松的縮寫。
雖然縮寫更寬松,但還是要避免用單字符進行命名,除了臨時變量和循環變量。
即使局部變量是final和不可改變的,也不應該把它示為常量,自然也不能用常量的規則去命名它。
臨時變量通常被取名為i,j,k,m和n,它們一般用于整型;c,d,e,它們一般用于字符型。 如: for (int i = 0; i < len ; i++)。
類型變量可用以下兩種風格之一進行命名:
單個的大寫字母,后面可以跟一個數字(如:E, T, X, T2)。
以類命名方式(參考3.2 類名),后面加個大寫的T(如:RequestT, FooBarT)。
更多還可參考~阿里巴巴Java開發手冊
全部小寫,采用下劃線命名法
必須以全部單詞小寫,單詞間以下劃線分割,使用名詞或名詞詞組。
所有Activity或Fragment的contentView必須與其類名對應,對應規則為:
將所有字母都轉為小寫,將類型和功能調換(也就是后綴變前綴)。
例如:activity_main.xml
dialog_描述.xml
例如:dialog_hint.xml
ppw_描述.xml
例如:ppw_info.xml
item_描述.xml
例如:item_city.xml
模塊_(位置)描述.xml
例如:activity_main_head.xml、activity_main_bottom.xml
注意:通用的包含項命名采用:項目名稱縮寫_描述.xml
例如:xxxx_title.xml
全部小寫,采用下劃線命名法,加前綴區分
命名模式:可加后綴 _small 表示小圖, _big 表示大圖,邏輯名稱可由多個單詞加下劃線組成,采用以下規則:
用途_模塊名_邏輯名稱 用途_模塊名_顏色 用途_邏輯名稱 用途_顏色
說明:用途也指控件類型(具體見UI控件縮寫表)
例如:
btn_main_home.png 按鍵
divider_maket_white.png 分割線
ic_edit.png 圖標
bg_main.png 背景
btn_red.png 紅色按鍵
btn_red_big.png 紅色大按鍵
ic_head_small.png 小頭像
bg_input.png 輸入框背景
divider_white.png 白色分割線
如果有多種形態如按鈕等除外如 btn_xx.xml(selector)
| 名稱 | 功能 |
|---|---|
btn_xx
|
按鈕圖片使用btn_整體效果(selector)
|
btn_xx_normal
|
按鈕圖片使用btn_正常情況效果
|
btn_xx_pressed
|
按鈕圖片使用btn_點擊時候效果
|
btn_xx_focused
|
state_focused聚焦效果
|
btn_xx_disabled
|
state_enabled (false)不可用效果
|
btn_xx_checked
|
state_checked選中效果
|
btn_xx_selected
|
state_selected選中效果
|
btn_xx_hovered
|
state_hovered懸停效果
|
btn_xx_checkable
|
state_checkable可選效果
|
btn_xx_activated
|
state_activated激活的
|
btn_xx_windowfocused
|
state_window_focused
|
bg_head
|
背景圖片使用bg_功能_說明
|
def_search_cell
|
默認圖片使用def_功能_說明
|
ic_more_help
|
圖標圖片使用ic_功能_說明
|
seg_list_line
|
具有分隔特征的圖片使用seg_功能_說明
|
sel_ok
|
選擇圖標使用sel_功能_說明
|
注意:使用AndroidStudio的插件SelectorChapek可以快速生成selector,前提是命名要規范。
全部小寫,采用下劃線命名法,加前綴區分。
具體動畫采用以下規則:
模塊名_邏輯名稱
邏輯名稱
refresh_progress.xml market_cart_add.xml market_cart_remove.xml
普通的tween動畫采用如下表格中的命名方式
// 前面為動畫的類型,后面為方向
| 動畫命名例子 | 規范寫法 |
|---|---|
fade_in
|
淡入 |
fade_out
|
淡出 |
push_down_in
|
從下方推入 |
push_down_out
|
從下方推出 |
push_left
|
推向左方 |
slide_in_from_top
|
從頭部滑動進入 |
zoom_enter
|
變形進入 |
slide_in
|
滑動進入 |
shrink_to_middle
|
中間縮小 |
colors的name命名使用下劃線命名法,在你的colors.xml文件中應該只是映射顏色的名稱一個ARGB值,而沒有其它的。不要使用它為不同的按鈕來定義ARGB值。
不要這樣做
<resources> <color name="button_foreground">#FFFFFFcolor> <color name="button_background">#2A91BDcolor> <color name="comment_background_inactive">#5F5F5Fcolor> <color name="comment_background_active">#939393color> <color name="comment_foreground">#FFFFFFcolor> <color name="comment_foreground_important">#FF9D2Fcolor> ... <color name="comment_shadow">#323232color>
使用這種格式,你會非常容易的開始重復定義ARGB值,這使如果需要改變基本色變的很復雜。同時,這些定義是跟一些環境關聯起來的,如button或者comment, 應該放到一個按鈕風格中,而不是在color.xml文件中。
相反,這樣做
<resources> <color name="white" >#FFFFFFcolor> <color name="gray_light">#DBDBDBcolor> <color name="gray" >#939393color> <color name="gray_dark" >#5F5F5Fcolor> <color name="black" >#323232color> <color name="green">#27D34Dcolor> <color name="blue">#2A91BDcolor> <color name="orange">#FF9D2Fcolor> <color name="red">#FF432Fcolor> resources>
向應用設計者那里要這個調色板,名稱不需要跟"green", "blue", 等等相同。 "brand_primary", "brand_secondary", "brand_negative" 這樣的名字也是完全可以接受的。 像這樣規范的顏色很容易修改或重構,會使應用一共使用了多少種不同的顏色變得非常清晰。 通常一個具有審美價值的UI來說,減少使用顏色的種類是非常重要的。
像對待colors.xml一樣對待dimens.xml文件 與定義顏色調色板一樣,你同時也應該定義一個空隙間隔和字體大小的“調色板”。 一個好的例子,如下所示:
<resources> <dimen name="font_larger">22spdimen> <dimen name="font_large">18spdimen> <dimen name="font_normal">15spdimen> <dimen name="font_small">12spdimen> <dimen name="spacing_huge">40dpdimen> <dimen name="spacing_large">24dpdimen> <dimen name="spacing_normal">14dpdimen> <dimen name="spacing_small">10dpdimen> <dimen name="spacing_tiny">4dpdimen> <dimen name="button_height_tall">60dpdimen> <dimen name="button_height_normal">40dpdimen> <dimen name="button_height_short">32dpdimen> resources>
布局時在寫 margins 和 paddings 時,你應該使用spacing_xxxx尺寸格式來布局,而不是像對待String字符串一樣直接寫值。 這樣寫會非常有感覺,會使組織和改變風格或布局是非常容易。
strings的name命名使用下劃線命名法,采用以下規則:模塊名+邏輯名稱
例如:
main_menu_about 主菜單按鍵文字 friend_title 好友模塊標題欄 friend_dialog_del 好友刪除提示login_check_email 登錄驗證 dialog_title 彈出框標題 button_ok 確認鍵 loading 加載文字
幾乎每個項目都需要適當的使用style文件,因為對于一個視圖來說有一個重復的外觀是很常見的,將所有的外觀細節屬性(colors, padding, font)放在style文件中。 在應用中對于大多數文本內容,起碼你應該有一個通用的style文件,例如:
<style name="ContentText"> <item name="android:textSize">@dimen/font_normalitem> <item name="android:textColor">@color/basic_blackitem> style>
應用到TextView 中:
"wrap_content" android:layout_height="wrap_content" android:text="@string/price" style="@style/ContentText" />
你或許需要為按鈕控件做同樣的事情,不要停止在那里。將一組相關的和重復android:****的屬性放到一個通用的style中。
將一個大的style文件分割成多個文件, 你可以有多個styles.xml 文件。Android SDK支持其它文件,styles這個文件名稱并沒有作用,起作用的是在文件 里xml的
標簽。因此你可以有多個style文件styles.xml,style_home.xml,style_item_details.xml,styles_forms.xml。 不同于資源文件路徑需要為系統構建起的有意義,在res/values目錄下的文件可以任意命名。
命名模式為:view縮寫_模塊名_邏輯名,比如btn_main_search 使用 AndroidStudio 的插件 ButterKnife Zelezny,生成注解非常方便,或者也可以使用Android Code Generator插件。
如果想對資源文件進行分包可以參考我這篇文章~Android Studio下對資源進行分包
Android開發存在著眾多版本的不同,比如compileSdkVersion、minSdkVersion、targetSdkVersion以及項目中依賴第三方庫的版本,不同的module及不同的開發人員都有不同的版本,所以需要一個統一版本規范的文件。
具體可以參考我寫的這篇博文~Android開發之版本統一規范
別再閉門造車了,用用新火的技術吧,安利一波~Android 流行框架查速表,順便帶上自己的干貨~Android開發人員不得不收集的代碼
希望team能用時下較新的技術,不建議自己造輪子或者使用停止維護的輪子,否則出了問題也提不了issue。
個人推薦team使用Retrofit, RxAndroid, OkHttp, Glide/Fresco, Gson/Fastjson, EventBus/AndroidEventBus, GreenDao,(Dagger2, Tinker)。
為了讓他人可以容易看懂你的代碼,請在關鍵地方做好注釋。
每個類完成后應該有作者姓名和聯系方式的注釋,對自己的代碼負責。
/** *
* author : Blankj * e-mail : xxx@xx * time : 2017/03/07 * desc : xxxx描述 * version: 1.0 *
*/ public class WelcomeActivity { ... }
具體可以在AS中自己配制,Setting → Editor → File and Code Templates → Includes → File Header,輸入
/** *
* author : ${USER} * e-mail : xxx@xx * time : ${YEAR}/${MONTH}/${DAY} * desc : xxxx描述 * version: 1.0 * </pre> */
這樣便可在每次新建類的時候自動加上該注釋。
每一個成員方法(包括自定義成員方法、覆蓋方法、屬性方法)的方法頭都必須做方法頭注釋,在方法前一行輸入/**回車,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();
}
塊注釋與其周圍的代碼在同一縮進級別。它們可以是/* ... */風格,也可以是// ...風格(// 后好帶一個空格)。對于多行的/* ... */注釋,后續行必須從*開始, 并且與前一行的*對齊。以下示例注釋都是OK的。
/* * This is // And so /* Or you can * okay. // is this. * even do this. */ */
注釋不要封閉在由星號或其它字符繪制的框架里。
Tip:在寫多行注釋時,如果你希望在必要時能重新換行(即注釋像段落風格一樣),那么使用/* ... */。
業務開發完成之后,開發人員做單元測試,單元測試完成之后,保證單元測試全部通過同時單元測試代碼覆蓋率達到一定程度(這個需要開發和測試約定,理論上越高越好),開發提測。
// TODO...
// TODO...
,?,?標簽
表1 UI控件縮寫表
| View | 縮寫 |
|---|---|
| TextView | txt |
| EditText | edit |
| Button | btn |
| ImageButton | ibtn |
| ImageView | img |
| ListView | lv |
| RadioGroup | rgroup |
| RadioButton | rbtn |
| ProgressBar | rbar |
| SeekBar | seek |
| CheckBox | cb |
| Spinner | spinner |
| TableLayout | table |
| TableRow | row |
| LinearLayout | ll |
| RelativeLayout | rl |
| ScrollView | scroll |
| SearchView | search |
| TabHost | thost |
| TabWidget | twidget |
表2 常見的英文單詞縮寫:
| 名稱 | 縮寫 |
|---|---|
| icon | ic (主要用在app的圖標) |
| color | cl(主要用于顏色值) |
| divider | di(主要用于分隔線,不僅包括Listview中的divider,還包括普通布局中的線) |
| selector | sl(主要用于某一view多種狀態,不僅包括Listview中的selector,還包括按鈕的selector) |
| average | avg |
| background | bg(主要用于布局和子布局的背景) |
| buffer | buf |
| control | ctrl |
| delete | del |
| document | doc |
| error | err |
| escape | esc |
| increment | inc |
| infomation | info |
| initial | init |
| image | img |
| Internationalization | I18N |
| length | len |
| library | lib |
| message | msg |
| password | pwd |
| position | pos |
| server | srv |
| string | str |
| temp | tmp |
| window | wnd(win) |
程序中使用單詞縮寫原則:不要用縮寫,除非該縮寫是約定俗成的。
本站文章版權歸原作者及原出處所有 。內容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責,本站只提供參考并不構成任何投資及應用建議。本站是一個個人學習交流的平臺,網站上部分文章為轉載,并不用于任何商業目的,我們已經盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯系我們,我們將根據著作權人的要求,立即更正或者刪除有關內容。本站擁有對此聲明的最終解釋權。