摘要
1 前言
為了有利于項(xiàng)目維護(hù)剂陡、增強(qiáng)代碼可讀性贯涎、提升 Code Review 效率以及規(guī)范團(tuán)隊(duì)安卓開發(fā),故提出以下安卓開發(fā)規(guī)范坑傅,該規(guī)范結(jié)合本人多年的開發(fā)經(jīng)驗(yàn)并吸取多家之精華,可謂是本人的嘔心瀝血之作,稱其為當(dāng)前最完善的安卓開發(fā)規(guī)范一點(diǎn)也不為過,如有更好建議砍濒,歡迎到 GitHub 提 issue,原文地址:Android 開發(fā)規(guī)范(完結(jié)版)硫麻。相關(guān) Demo爸邢,可以查看我的 Android 開發(fā)工具類集合項(xiàng)目:Android 開發(fā)人員不得不收集的代碼。后續(xù)可能會(huì)根據(jù)該規(guī)范出一個(gè) CheckStyle 插件來檢查是否規(guī)范庶香,當(dāng)然也支持在 CI 上運(yùn)行甲棍。
2 AS 規(guī)范
工欲善其事,必先利其器赶掖。
盡量使用最新的穩(wěn)定版的 IDE 進(jìn)行開發(fā)感猛;
編碼格式統(tǒng)一為UTF-8;
編輯完 .java奢赂、.xml 等文件后一定要格式化陪白,格式化,格式化(如果團(tuán)隊(duì)有公共的樣式包膳灶,那就遵循它咱士,否則統(tǒng)一使用 AS 默認(rèn)模板即可);
刪除多余的 import轧钓,減少警告出現(xiàn)序厉,可利用 AS 的 Optimize Imports(Settings -> Keymap -> Optimize Imports)快捷鍵;
Android 開發(fā)者工具可以參考這里:Android 開發(fā)者工具毕箍;
3 命名規(guī)范
代碼中的命名嚴(yán)禁使用拼音與英文混合的方式弛房,更不允許直接使用中文的方式。正確的英文拼寫和語法可以讓閱讀者易于理解而柑,避免歧義文捶。
注意:即使純拼音命名方式也要避免采用荷逞。但alibaba、taobao粹排、youku种远、hangzhou等國際通用的名稱,可視同英文顽耳。
3.1 包名
包名全部小寫坠敷,連續(xù)的單詞只是簡(jiǎn)單地連接起來,不使用下劃線斧抱,采用反域名命名規(guī)則常拓,全部使用小寫字母。一級(jí)包名是頂級(jí)域名辉浦,通常為com、edu茎辐、gov宪郊、net、org等拖陆,二級(jí)包名為公司名弛槐,三級(jí)包名根據(jù)應(yīng)用進(jìn)行命名,后面就是對(duì)包名的劃分了依啰,關(guān)于包名的劃分乎串,推薦采用 PBF(按功能分包 Package By Feature),一開始我們采用的也是 PBL(按層分包 Package By Layer)速警,很坑爹叹誉。PBF 可能不是很好區(qū)分在哪個(gè)功能中,不過也比 PBL 要好找很多闷旧,且 PBF 與 PBL 相比較有如下優(yōu)勢(shì):
package 內(nèi)高內(nèi)聚长豁,package 間低耦合
哪塊要添新功能,只改某一個(gè) package 下的東西忙灼。
PBL 降低了代碼耦合匠襟,但帶來了 package 耦合,要添新功能该园,需要改 model酸舍、dbHelper、view里初、service 等等啃勉,需要改動(dòng)好幾個(gè) package 下的代碼,改動(dòng)的地方越多青瀑,越容易產(chǎn)生新問題璧亮,不是嗎萧诫?
PBF 的話 featureA 相關(guān)的所有東西都在 featureA 包,feature 內(nèi)高內(nèi)聚枝嘶、高度模塊化帘饶,不同 feature 之間低耦合,相關(guān)的東西都放在一起群扶,還好找及刻。
package 有私有作用域(package-private scope)
你負(fù)責(zé)開發(fā)這塊功能,這個(gè)目錄下所有東西都是你的竞阐。
PBL 的方式是把所有工具方法都放在 util 包下缴饭,小張開發(fā)新功能時(shí)候發(fā)現(xiàn)需要一個(gè) xxUtil,但它又不是通用的骆莹,那應(yīng)該放在哪里颗搂?沒辦法,按照分層原則幕垦,我們還得放在 util 包下丢氢,好像不太合適,但放在其它包更不合適先改,功能越來越多疚察,util 類也越定義越多。后來小李負(fù)責(zé)開發(fā)一塊功能時(shí)發(fā)現(xiàn)需要一個(gè) xxUtil仇奶,同樣不通用貌嫡,去 util 包一看,怎么已經(jīng)有了该溯,而且還沒法復(fù)用岛抄,只好放棄 xx 這個(gè)名字,改為 xxxUtil……朗伶,因?yàn)?PBL 的 package 沒有私有作用域弦撩,每一個(gè)包都是 public(跨包方法調(diào)用是很平常的事情,每一個(gè)包對(duì)其它包來說都是可訪問的)论皆;如果是 PBF益楼,小張的 xxUtil 自然放在 featureA 下,小李的 xxUtil 在 featureB 下点晴,如果覺得 util 好像是通用的感凤,就去 util 包看看要不要把工具方法添進(jìn) xxUtil, class 命名沖突沒有了。
PBF 的 package 有私有作用域粒督,featureA 不應(yīng)該訪問 featureB 下的任何東西(如果非訪問不可陪竿,那就說明接口定義有問題)。
很容易刪除功能
統(tǒng)計(jì)發(fā)現(xiàn)新功能沒人用,這個(gè)版本那塊功能得去掉族跛。
如果是 PBL闰挡,得從功能入口到整個(gè)業(yè)務(wù)流程把受到牽連的所有能刪的代碼和 class 都揪出來刪掉,一不小心就完蛋礁哄。
如果是 PBF长酗,好說,先刪掉對(duì)應(yīng)包桐绒,再刪掉功能入口(刪掉包后入口肯定報(bào)錯(cuò)了)夺脾,完事。
高度抽象
解決問題的一般方法是從抽象到具體茉继,PBF 包名是對(duì)功能模塊的抽象咧叭,包內(nèi)的 class 是實(shí)現(xiàn)細(xì)節(jié),符合從抽象到具體烁竭,而 PBL 弄反了菲茬。
PBF 從確定 AppName 開始,根據(jù)功能模塊劃分 package颖变,再考慮每塊的具體實(shí)現(xiàn)細(xì)節(jié)生均,而 PBL 從一開始就要考慮要不要 dao 層,要不要 com 層等等腥刹。
只通過 class 來分離邏輯代碼
PBL 既分離 class 又分離 package,而 PBF 只通過 class 來分離邏輯代碼汉买。
沒有必要通過 package 分離衔峰,因?yàn)?PBL 中也可能出現(xiàn)尷尬的情況:
├──service
????├──MainService.java
按照 PBL, service 包下的所有東西都是 Service,應(yīng)該不需要 Service 后綴蛙粘,但實(shí)際上通常為了方便垫卤,直接 import service 包,Service 后綴是為了避免引入的 class 和當(dāng)前包下的 class 命名沖突出牧,當(dāng)然穴肘,不用后綴也可以,得寫清楚包路徑舔痕,比如new com.domain.service.MainService()评抚,麻煩;而 PBF 就很方便伯复,無需 import慨代,直接new MainService()即可。
package 的大小有意義了
PBL 中包的大小無限增長(zhǎng)是合理的啸如,因?yàn)楣δ茉教碓蕉嗍坛祝?PBF 中包太大(包里 class 太多)表示這塊需要重構(gòu)(劃分子包)。
如要知道更多好處叮雳,可以查看這篇博文:Package by features, not layers想暗,當(dāng)然妇汗,我們大谷歌也有相應(yīng)的 Sample:todo-mvp,其結(jié)構(gòu)如下所示说莫,很值得學(xué)習(xí)杨箭。
com└──example└──android└──architecture└──blueprints└──todoapp├──BasePresenter.java├──BaseView.java├──addedittask│? ├──AddEditTaskActivity.java│? ├──AddEditTaskContract.java│? ├──AddEditTaskFragment.java│? └──AddEditTaskPresenter.java├──data│? ├──Task.java│? └──source│? ? ? ├──TasksDataSource.java│? ? ? ├──TasksRepository.java│? ? ? ├──local│? ? ? │? ├──TasksDbHelper.java│? ? ? │? ├──TasksLocalDataSource.java│? ? ? │? └──TasksPersistenceContract.java│? ? ? └──remote│? ? ? ? ? └──TasksRemoteDataSource.java├──statistics│? ├──StatisticsActivity.java│? ├──StatisticsContract.java│? ├──StatisticsFragment.java│? └──StatisticsPresenter.java├──taskdetail│? ├──TaskDetailActivity.java│? ├──TaskDetailContract.java│? ├──TaskDetailFragment.java│? └──TaskDetailPresenter.java├──tasks│? ├──ScrollChildSwipeRefreshLayout.java│? ├──TasksActivity.java│? ├──TasksContract.java│? ├──TasksFilterType.java│? ├──TasksFragment.java│? └──TasksPresenter.java└──util├──ActivityUtils.java├──EspressoIdlingResource.java└──SimpleCountingIdlingResource.java
參考以上的代碼結(jié)構(gòu),按功能分包具體可以這樣做:
com└── domain? ? └── app? ? ? ? ├── App.java 定義 Application 類? ? ? ? ├── Config.java 定義配置數(shù)據(jù)(常量)? ? ? ? ├── base 基礎(chǔ)組件? ? ? ? ├── custom_view 自定義視圖? ? ? ? ├── data 數(shù)據(jù)處理? ? ? ? │? ├── DataManager.java 數(shù)據(jù)管理器唬滑,? ? ? ? │? ├── local 來源于本地的數(shù)據(jù)告唆,比如 SP,Database晶密,F(xiàn)ile? ? ? ? │? ├── model 定義 model(數(shù)據(jù)結(jié)構(gòu)以及getter/setter擒悬、compareTo、equals 等等稻艰,不含復(fù)雜操作)? ? ? ? │? └── remote 來源于遠(yuǎn)端的數(shù)據(jù)? ? ? ? ├── feature 功能? ? ? ? │? ├── feature0 功能0│? │? ├── feature0Activity.java? ? ? ? │? │? ├── feature0Fragment.java? ? ? ? │? │? ├── xxAdapter.java? ? ? ? │? │? └── ... 其他class│? └── ...其他功能? ? ? ? ├── injection 依賴注入? ? ? ? ├── util 工具類? ? ? ? └── widget 小部件
3.2 類名
類名都以UpperCamelCase風(fēng)格編寫懂牧。
類名通常是名詞或名詞短語,接口名稱有時(shí)可能是形容詞或形容詞短語∽鹞穑現(xiàn)在還沒有特定的規(guī)則或行之有效的約定來命名注解類型僧凤。
名詞,采用大駝峰命名法元扔,盡量避免縮寫躯保,除非該縮寫是眾所周知的, 比如 HTML澎语、URL途事,如果類名稱中包含單詞縮寫,則單詞縮寫的每個(gè)字母均應(yīng)大寫擅羞。
類描述例如
Activity類Activity為后綴標(biāo)識(shí)歡迎頁面類WelcomeActivity
Adapter類Adapter為后綴標(biāo)識(shí)新聞詳情適配器NewsDetailAdapter
解析類Parser為后綴標(biāo)識(shí)首頁解析類HomePosterParser
工具方法類Utils或Manager為后綴標(biāo)識(shí)線程池管理類:ThreadPoolManager
日志工具類:LogUtils(Logger也可)
打印工具類:PrinterUtils
數(shù)據(jù)庫類以DBHelper后綴標(biāo)識(shí)新聞數(shù)據(jù)庫:NewsDBHelper
Service類以Service為后綴標(biāo)識(shí)時(shí)間服務(wù)TimeService
BroadcastReceiver類以Receiver為后綴標(biāo)識(shí)推送接收J(rèn)PushReceiver
ContentProvider類以Provider為后綴標(biāo)識(shí)ShareProvider
自定義的共享基礎(chǔ)類以Base開頭BaseActivity,BaseFragment
測(cè)試類的命名以它要測(cè)試的類的名稱開始尸变,以 Test 結(jié)束。例如:HashTest或HashIntegrationTest减俏。
接口(interface):命名規(guī)則與類一樣采用大駝峰命名法召烂,多以 able 或 ible 結(jié)尾,如interface Runnable娃承、interface Accessible奏夫。
注意:如果項(xiàng)目采用 MVP,所有 Model草慧、View桶蛔、Presenter 的接口都以 I 為前綴,不加后綴漫谷,其他的接口采用上述命名規(guī)則仔雷。
3.3 方法名
方法名都以lowerCamelCase風(fēng)格編寫。
方法名通常是動(dòng)詞或動(dòng)詞短語。
方法說明
initXX()初始化相關(guān)方法碟婆,使用 init 為前綴標(biāo)識(shí)电抚,如初始化布局initView()
isXX(),checkXX()方法返回值為 boolean 型的請(qǐng)使用 is/check 為前綴標(biāo)識(shí)
getXX()返回某個(gè)值的方法,使用 get 為前綴標(biāo)識(shí)
setXX()設(shè)置某個(gè)屬性值
handleXX(),processXX()對(duì)數(shù)據(jù)進(jìn)行處理的方法
displayXX(),showXX()彈出提示框和提示信息竖共,使用 display/show 為前綴標(biāo)識(shí)
updateXX()更新數(shù)據(jù)
saveXX(),insertXX()保存或插入數(shù)據(jù)
resetXX()重置數(shù)據(jù)
clearXX()清除數(shù)據(jù)
removeXX(),deleteXX()移除數(shù)據(jù)或者視圖等蝙叛,如removeView()
drawXX()繪制數(shù)據(jù)或效果相關(guān)的,使用 draw 前綴標(biāo)識(shí)
3.4 常量名
常量名命名模式為CONSTANT_CASE公给,全部字母大寫借帘,用下劃線分隔單詞。那到底什么算是一個(gè)常量淌铐?
每個(gè)常量都是一個(gè)static final字段肺然,但不是所有static final字段都是常量。在決定一個(gè)字段是否是一個(gè)常量時(shí)腿准,得考慮它是否真的感覺像是一個(gè)常量际起。例如,如果觀測(cè)任何一個(gè)該實(shí)例的狀態(tài)是可變的吐葱,則它幾乎肯定不會(huì)是一個(gè)常量街望。只是永遠(yuǎn)不打算改變的對(duì)象一般是不夠的,它要真的一直不變才能將它示為常量弟跑。
// ConstantsstaticfinalintNUMBER =5;staticfinalImmutableListNAMES = ImmutableList.of("Ed","Ann");staticfinalJoiner COMMA_JOINER = Joiner.on(',');// because Joiner is immutablestaticfinalSomeMutableType[] EMPTY_ARRAY = {};enumSomeEnum { ENUM_CONSTANT }// Not constantsstaticString nonFinal ="non-final";finalString nonStatic ="non-static";staticfinalSetmutableCollection =newHashSet();staticfinalImmutableSetmutableElements = ImmutableSet.of(mutable);staticfinalLogger logger = Logger.getLogger(MyClass.getName());staticfinalString[] nonEmptyArray = {"these","can","change"};
3.5 非常量字段名
非常量字段名以lowerCamelCase風(fēng)格的基礎(chǔ)上改造為如下風(fēng)格:基本結(jié)構(gòu)為scope{Type0}VariableName{Type1}灾前、type0VariableName{Type1}、variableName{Type1}孟辑。
說明:{}中的內(nèi)容為可選豫柬。
注意:所有的 VO(值對(duì)象)統(tǒng)一采用標(biāo)準(zhǔn)的 lowerCamelCase 風(fēng)格編寫,所有的 DTO(數(shù)據(jù)傳輸對(duì)象)就按照接口文檔中定義的字段名編寫扑浸。
3.5.1 scope(范圍)
非公有,非靜態(tài)字段命名以m開頭燕偶。
靜態(tài)字段命名以s開頭喝噪。
其他字段以小寫字母開頭。
例如:
publicclassMyClass{publicintpublicField;privatestaticMyClass sSingleton;intmPackagePrivate;privateintmPrivate;protectedintmProtected;}
使用 1 個(gè)字符前綴來表示作用范圍指么,1 個(gè)字符的前綴必須小寫酝惧,前綴后面是由表意性強(qiáng)的一個(gè)單詞或多個(gè)單詞組成的名字,而且每個(gè)單詞的首寫字母大寫伯诬,其它字母小寫晚唇,這樣保證了對(duì)變量名能夠進(jìn)行正確的斷句。
3.5.2 Type0(控件類型)
考慮到 Android 眾多的 UI 控件盗似,為避免控件和普通成員變量混淆以及更好地表達(dá)意思哩陕,所有用來表示控件的成員變量統(tǒng)一加上控件縮寫作為前綴(具體見附錄UI 控件縮寫表)。
例如:mIvAvatar、rvBooks悍及、flContainer闽瓢。
3.5.3 VariableName(變量名)
變量名中可能會(huì)出現(xiàn)量詞,我們需要?jiǎng)?chuàng)建統(tǒng)一的量詞心赶,它們更容易理解扣讼,也更容易搜索。
例如:mFirstBook缨叫、mPreBook椭符、curBook。
量詞列表量詞后綴說明
First一組變量中的第一個(gè)
Last一組變量中的最后一個(gè)
Next一組變量中的下一個(gè)
Pre一組變量中的上一個(gè)
Cur一組變量中的當(dāng)前變量
3.5.4 Type1(數(shù)據(jù)類型)
對(duì)于表示集合或者數(shù)組的非常量字段名耻姥,我們可以添加后綴來增強(qiáng)字段的可讀性销钝,比如:
集合添加如下后綴:List、Map咏闪、Set曙搬。
數(shù)組添加如下后綴:Arr。
例如:mIvAvatarList鸽嫂、userArr纵装、firstNameSet。
注意:如果數(shù)據(jù)類型不確定的話据某,比如表示的是很多書橡娄,那么使用其復(fù)數(shù)形式來表示也可,例如mBooks癣籽。
3.6 參數(shù)名
參數(shù)名以lowerCamelCase風(fēng)格編寫挽唉,參數(shù)應(yīng)該避免用單個(gè)字符命名。
3.7 局部變量名
局部變量名以lowerCamelCase風(fēng)格編寫筷狼,比起其它類型的名稱瓶籽,局部變量名可以有更為寬松的縮寫。
雖然縮寫更寬松埂材,但還是要避免用單字符進(jìn)行命名塑顺,除了臨時(shí)變量和循環(huán)變量。
即使局部變量是final和不可改變的俏险,也不應(yīng)該把它示為常量严拒,自然也不能用常量的規(guī)則去命名它。
3.8 臨時(shí)變量
臨時(shí)變量通常被取名為i竖独、j裤唠、k、m和n莹痢,它們一般用于整型种蘸;c墓赴、d、e劈彪,它們一般用于字符型竣蹦。 如:for (int i = 0; i < len; i++)。
3.9 類型變量名
類型變量可用以下兩種風(fēng)格之一進(jìn)行命名:
單個(gè)的大寫字母沧奴,后面可以跟一個(gè)數(shù)字(如:E,T,X,T2)痘括。
以類命名方式(參考3.2 類名)辛臊,后面加個(gè)大寫的 T(如:RequestT,FooBarT)涂炎。
更多還可參考:阿里巴巴 Java 開發(fā)手冊(cè)
4 代碼樣式規(guī)范
4.1 使用標(biāo)準(zhǔn)大括號(hào)樣式
左大括號(hào)不單獨(dú)占一行,與其前面的代碼位于同一行:
classMyClass{intfunc(){if(something) {// ...}elseif(somethingElse) {// ...}else{// ...}? ? }}
我們需要在條件語句周圍添加大括號(hào)宝磨。例外情況:如果整個(gè)條件語句(條件和主體)適合放在同一行疮绷,那么您可以(但不是必須)將其全部放在一行上翰舌。例如,我們接受以下樣式:
if(condition) {? ? body();}
同樣也接受以下樣式:
if(condition) body();
但不接受以下樣式:
if(condition)? ? body();// bad!
4.2 編寫簡(jiǎn)短方法
在可行的情況下冬骚,盡量編寫短小精煉的方法椅贱。我們了解,有些情況下較長(zhǎng)的方法是恰當(dāng)?shù)闹欢常虼藢?duì)方法的代碼長(zhǎng)度沒有做出硬性限制庇麦。如果某個(gè)方法的代碼超出 40 行,請(qǐng)考慮是否可以在不破壞程序結(jié)構(gòu)的前提下對(duì)其拆解喜德。
4.3 類成員的順序
這并沒有唯一的正確解決方案山橄,但如果都使用一致的順序?qū)?huì)提高代碼的可讀性,推薦使用如下排序:
常量
字段
構(gòu)造函數(shù)
重寫函數(shù)和回調(diào)
公有函數(shù)
私有函數(shù)
內(nèi)部類或接口
例如:
publicclassMainActivityextendsActivity{privatestaticfinalString TAG = MainActivity.class.getSimpleName();privateString mTitle;privateTextView mTextViewTitle;@OverridepublicvoidonCreate(){? ? ? ? ...? ? }publicvoidsetTitle(String title){? ? ? ? mTitle = title;? ? }privatevoidsetUpView(){? ? ? ? ...? ? }staticclassAnInnerClass{? ? }}
如果類繼承于 Android 組件(例如Activity或Fragment)舍悯,那么把重寫函數(shù)按照他們的生命周期進(jìn)行排序是一個(gè)非常好的習(xí)慣航棱,例如,Activity實(shí)現(xiàn)了onCreate()萌衬、onDestroy()饮醇、onPause()、onResume()秕豫,它的正確排序如下所示:
publicclassMainActivityextendsActivity{//Order matches Activity lifecycle@OverridepublicvoidonCreate(){}@OverridepublicvoidonResume(){}@OverridepublicvoidonPause(){}@OverridepublicvoidonDestroy(){}}
4.4 函數(shù)參數(shù)的排序
在 Android 開發(fā)過程中驳阎,Context在函數(shù)參數(shù)中是再常見不過的了,我們最好把Context作為其第一個(gè)參數(shù)馁蒂。
正相反,我們把回調(diào)接口應(yīng)該作為其最后一個(gè)參數(shù)蜘腌。
例如:
// Context always goes firstpublicUserloadUser(Context context,intuserId);// Callbacks always go lastpublicvoidloadUserAsync(Context context,intuserId, UserCallback callback);
4.5 字符串常量的命名和值
Android SDK 中的很多類都用到了鍵值對(duì)函數(shù)沫屡,比如SharedPreferences、Bundle撮珠、Intent沮脖,所以金矛,即便是一個(gè)小應(yīng)用,我們最終也不得不編寫大量的字符串常量勺届。
當(dāng)時(shí)用到這些類的時(shí)候驶俊,我們必須將它們的鍵定義為static final字段,并遵循以下指示作為前綴免姿。
類字段名前綴
SharedPreferencesPREF_
BundleBUNDLE_
Fragment ArgumentsARGUMENT_
Intent ExtraEXTRA_
Intent ActionACTION_
說明:雖然Fragment.getArguments()得到的也是Bundle饼酿,但因?yàn)檫@是Bundle的常用用法,所以特意為此定義一個(gè)不同的前綴胚膊。
例如:
// 注意:字段的值與名稱相同以避免重復(fù)問題staticfinalString PREF_EMAIL ="PREF_EMAIL";staticfinalString BUNDLE_AGE ="BUNDLE_AGE";staticfinalString ARGUMENT_USER_ID ="ARGUMENT_USER_ID";// 與意圖相關(guān)的項(xiàng)使用完整的包名作為值的前綴staticfinalString EXTRA_SURNAME ="com.myapp.extras.EXTRA_SURNAME";staticfinalString ACTION_OPEN_USER ="com.myapp.action.ACTION_OPEN_USER";
4.6 Activities 和 Fragments 的傳參
當(dāng)Activity或Fragment傳遞數(shù)據(jù)通過Intent或Bundle時(shí)故俐,不同值的鍵須遵循上一條所提及到的。
當(dāng)Activity或Fragment啟動(dòng)需要傳遞參數(shù)時(shí)紊婉,那么它需要提供一個(gè)public static的函數(shù)來幫助啟動(dòng)或創(chuàng)建它药版。
這方面,AS 已幫你寫好了相關(guān)的 Live Templates喻犁,啟動(dòng)相關(guān)Activity的只需要在其內(nèi)部輸入starter即可生成它的啟動(dòng)器槽片,如下所示:
publicstaticvoidstart(Context context, User user){? ? ? Intent starter =newIntent(context, MainActivity.class);? ? ? starter.putParcelableExtra(EXTRA_USER, user);? ? ? context.startActivity(starter);}
同理,啟動(dòng)相關(guān)Fragment在其內(nèi)部輸入newInstance即可肢础,如下所示:
publicstaticMainFragmentnewInstance(User user){? ? ? Bundle args =newBundle();? ? ? args.putParcelable(ARGUMENT_USER, user);? ? ? MainFragment fragment =newMainFragment();? ? ? fragment.setArguments(args);returnfragment;}
注意:這些函數(shù)需要放在onCreate()之前的類的頂部还栓;如果我們使用了這種方式,那么extras和arguments的鍵應(yīng)該是private的乔妈,因?yàn)樗鼈儾辉傩枰┞督o其他類來使用蝙云。
4.7 行長(zhǎng)限制
代碼中每一行文本的長(zhǎng)度都應(yīng)該不超過 100 個(gè)字符。雖然關(guān)于此規(guī)則存在很多爭(zhēng)論路召,但最終決定仍是以 100 個(gè)字符為上限勃刨,如果行長(zhǎng)超過了 100(AS 窗口右側(cè)的豎線就是設(shè)置的行寬末尾 ),我們通常有兩種方法來縮減行長(zhǎng)股淡。
提取一個(gè)局部變量或方法(最好)身隐。
使用換行符將一行換成多行。
不過存在以下例外情況:
如果備注行包含長(zhǎng)度超過 100 個(gè)字符的示例命令或文字網(wǎng)址唯灵,那么為了便于剪切和粘貼贾铝,該行可以超過 100 個(gè)字符。
導(dǎo)入語句行可以超出此限制埠帕,因?yàn)橛脩艉苌贂?huì)看到它們(這也簡(jiǎn)化了工具編寫流程)垢揩。
4.7.1 換行策略
這沒有一個(gè)準(zhǔn)確的解決方案來決定如何換行,通常不同的解決方案都是有效的敛瓷,但是有一些規(guī)則可以應(yīng)用于常見的情況叁巨。
4.7.1.1 操作符的換行
除賦值操作符之外,我們把換行符放在操作符之前呐籽,例如:
intlongName = anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne? ? ? ? + theFinalOne;
賦值操作符的換行我們放在其后锋勺,例如:
intlongName =? ? ? ? anotherVeryLongVariable + anEvenLongerOne - thisRidiculousLongOne + theFinalOne;
4.7.1.2 函數(shù)鏈的換行
當(dāng)同一行中調(diào)用多個(gè)函數(shù)時(shí)(比如使用構(gòu)建器時(shí))蚀瘸,對(duì)每個(gè)函數(shù)的調(diào)用應(yīng)該在新的一行中,我們把換行符插入在.之前庶橱。
例如:
Picasso.with(context).load("https://blankj.com/images/avatar.jpg").into(ivAvatar);
我們應(yīng)該使用如下規(guī)則:
Picasso.with(context)? ? ? ? .load("https://blankj.com/images/avatar.jpg")? ? ? ? .into(ivAvatar);
4.7.1.3 多參數(shù)的換行
當(dāng)一個(gè)方法有很多參數(shù)或者參數(shù)很長(zhǎng)的時(shí)候贮勃,我們應(yīng)該在每個(gè),后面進(jìn)行換行。
比如:
loadPicture(context,"https://blankj.com/images/avatar.jpg", ivAvatar,"Avatar of the user", clickListener);
我們應(yīng)該使用如下規(guī)則:
loadPicture(context,"https://blankj.com/images/avatar.jpg",? ? ? ? ivAvatar,"Avatar of the user",? ? ? ? clickListener);
4.7.1.4 RxJava 鏈?zhǔn)降膿Q行
RxJava 的每個(gè)操作符都需要換新行苏章,并且把換行符插入在.之前寂嘉。
例如:
publicObservablesyncLocations(){returnmDatabaseHelper.getAllLocations()? ? ? ? ? ? .concatMap(newFunc1>() {@OverridepublicObservable call(Location location) {returnmRetrofitService.getLocation(location.id);? ? ? ? ? ? ? ? }? ? ? ? ? ? })? ? ? ? ? ? .retry(newFunc2() {@OverridepublicBooleancall(Integer numRetries, Throwable throwable){returnthrowableinstanceofRetrofitError;? ? ? ? ? ? ? ? }? ? ? ? ? ? });}
5 資源文件規(guī)范
資源文件命名為全部小寫,采用下劃線命名法布近。
如果想對(duì)資源文件進(jìn)行分包可以參考我這篇文章:Android Studio 下對(duì)資源進(jìn)行分包垫释。
5.1 動(dòng)畫資源文件(anim/ 和 animator/)
安卓主要包含屬性動(dòng)畫和視圖動(dòng)畫,其視圖動(dòng)畫包括補(bǔ)間動(dòng)畫和逐幀動(dòng)畫撑瞧。屬性動(dòng)畫文件需要放在res/animator/目錄下棵譬,視圖動(dòng)畫文件需放在res/anim/目錄下。
命名規(guī)則:{模塊名_}邏輯名稱预伺。
說明:{}中的內(nèi)容為可選订咸,邏輯名稱可由多個(gè)單詞加下劃線組成。
例如:refresh_progress.xml酬诀、market_cart_add.xml脏嚷、market_cart_remove.xml。
如果是普通的補(bǔ)間動(dòng)畫或者屬性動(dòng)畫瞒御,可采用:動(dòng)畫類型_方向的命名方式父叙。
例如:
名稱說明
fade_in淡入
fade_out淡出
push_down_in從下方推入
push_down_out從下方推出
push_left推向左方
slide_in_from_top從頭部滑動(dòng)進(jìn)入
zoom_enter變形進(jìn)入
slide_in滑動(dòng)進(jìn)入
shrink_to_middle中間縮小
5.2 顏色資源文件(color/)
專門存放顏色相關(guān)的資源文件。
命名規(guī)則:類型_邏輯名稱肴裙。
例如:sel_btn_font.xml趾唱。
顏色資源也可以放于res/drawable/目錄,引用時(shí)則用@drawable來引用蜻懦,但不推薦這么做甜癞,最好還是把兩者分開。
5.3 圖片資源文件(drawable/ 和 mipmap/)
res/drawable/目錄下放的是位圖文件(.png宛乃、.9.png悠咱、.jpg、.gif)或編譯為可繪制對(duì)象資源子類型的 XML 文件征炼,而res/mipmap/目錄下放的是不同密度的啟動(dòng)圖標(biāo)析既,所以res/mipmap/只用于存放啟動(dòng)圖標(biāo),其余圖片資源文件都應(yīng)該放到res/drawable/目錄下谆奥。
命名規(guī)則:類型{_模塊名}_邏輯名稱渡贾、類型{_模塊名}_顏色。
說明:{}中的內(nèi)容為可選雄右;類型可以是可繪制對(duì)象資源類型空骚,也可以是控件類型(具體見附錄UI 控件縮寫表);最后可加后綴_small表示小圖擂仍,_big表示大圖囤屹。
例如:
名稱說明
btn_main_about.png主頁關(guān)于按鍵類型_模塊名_邏輯名稱
btn_back.png返回按鍵類型_邏輯名稱
divider_maket_white.png商城白色分割線類型_模塊名_顏色
ic_edit.png編輯圖標(biāo)類型_邏輯名稱
bg_main.png主頁背景類型_邏輯名稱
btn_red.png紅色按鍵類型_顏色
btn_red_big.png紅色大按鍵類型_顏色
ic_head_small.png小頭像圖標(biāo)類型_邏輯名稱
bg_input.png輸入框背景類型_邏輯名稱
divider_white.png白色分割線類型_顏色
bg_main_head.png主頁頭部背景類型_模塊名_邏輯名稱
def_search_cell.png搜索頁面默認(rèn)單元圖片類型_模塊名_邏輯名稱
ic_more_help.png更多幫助圖標(biāo)類型_邏輯名稱
divider_list_line.png列表分割線類型_邏輯名稱
sel_search_ok.xml搜索界面確認(rèn)選擇器類型_模塊名_邏輯名稱
shape_music_ring.xml音樂界面環(huán)形形狀類型_模塊名_邏輯名稱
如果有多種形態(tài),如按鈕選擇器:sel_btn_xx.xml逢渔,采用如下命名:
名稱說明
sel_btn_xx作用在btn_xx上的selector
btn_xx_normal默認(rèn)狀態(tài)效果
btn_xx_pressedstate_pressed點(diǎn)擊效果
btn_xx_focusedstate_focused聚焦效果
btn_xx_disabledstate_enabled不可用效果
btn_xx_checkedstate_checked選中效果
btn_xx_selectedstate_selected選中效果
btn_xx_hoveredstate_hovered懸停效果
btn_xx_checkablestate_checkable可選效果
btn_xx_activatedstate_activated激活效果
btn_xx_window_focusedstate_window_focused窗口聚焦效果
注意:使用 Android Studio 的插件 SelectorChapek 可以快速生成 selector肋坚,前提是命名要規(guī)范。
5.4 布局資源文件(layout/)
命名規(guī)則:類型_模塊名肃廓、類型{_模塊名}_邏輯名稱智厌。
說明:{}中的內(nèi)容為可選。
例如:
名稱說明
activity_main.xml主窗體類型_模塊名
activity_main_head.xml主窗體頭部類型_模塊名_邏輯名稱
fragment_music.xml音樂片段類型_模塊名
fragment_music_player.xml音樂片段的播放器類型_模塊名_邏輯名稱
dialog_loading.xml加載對(duì)話框類型_邏輯名稱
ppw_info.xml信息彈窗(PopupWindow)類型_邏輯名稱
item_main_song.xml主頁歌曲列表項(xiàng)類型_模塊名_邏輯名稱
5.5 菜單資源文件(menu/)
菜單相關(guān)的資源文件應(yīng)放在該目錄下盲赊。
命名規(guī)則:{模塊名_}邏輯名稱
說明:{}中的內(nèi)容為可選铣鹏。
例如:main_drawer.xml、navigation.xml哀蘑。
5.6 values 資源文件(values/)
values/資源文件下的文件都以s結(jié)尾诚卸,如attrs.xml、colors.xml绘迁、dimens.xml合溺,起作用的不是文件名稱,而是<resources>標(biāo)簽下的各種標(biāo)簽缀台,比如<style>決定樣式棠赛,<color>決定顏色,所以膛腐,可以把一個(gè)大的xml文件分割成多個(gè)小的文件睛约,比如可以有多個(gè)style文件,如styles.xml依疼、styles_home.xml痰腮、styles_item_details.xml、styles_forms.xml律罢。
5.6.1 colors.xml
<color>的name命名使用下劃線命名法膀值,在你的colors.xml文件中應(yīng)該只是映射顏色的名稱一個(gè) ARGB 值,而沒有其它的误辑。不要使用它為不同的按鈕來定義 ARGB 值沧踏。
例如,不要像下面這樣做:
#FFFFFF#2A91BD#5F5F5F#939393#FFFFFF#FF9D2F...#323232
使用這種格式巾钉,會(huì)非常容易重復(fù)定義 ARGB 值翘狱,而且如果應(yīng)用要改變基色的話會(huì)非常困難。同時(shí)砰苍,這些定義是跟一些環(huán)境關(guān)聯(lián)起來的潦匈,如button或者comment阱高,應(yīng)該放到一個(gè)按鈕風(fēng)格中,而不是在colors.xml文件中茬缩。
相反赤惊,應(yīng)該這樣做:
<!-- grayscale -->#FFFFFF#DBDBDB#939393#5F5F5F#323232<!-- basic colors -->#27D34D#2A91BD#FF9D2F#FF432F
向應(yīng)用設(shè)計(jì)者那里要這個(gè)調(diào)色板,名稱不需要跟"green"凰锡、"blue"等等相同未舟。"brand_primary"、"brand_secondary"掂为、"brand_negative"這樣的名字也是完全可以接受的裕膀。像這樣規(guī)范的顏色很容易修改或重構(gòu),會(huì)使應(yīng)用一共使用了多少種不同的顏色變得非常清晰勇哗。通常一個(gè)具有審美價(jià)值的 UI 來說昼扛,減少使用顏色的種類是非常重要的。
注意:如果某些顏色和主題有關(guān)智绸,那就單獨(dú)寫一個(gè)colors_theme.xml野揪。
5.6.2 dimens.xml
像對(duì)待colors.xml一樣對(duì)待dimens.xml文件,與定義顏色調(diào)色板一樣瞧栗,你同時(shí)也應(yīng)該定義一個(gè)空隙間隔和字體大小的“調(diào)色板”斯稳。 一個(gè)好的例子,如下所示:
<!-- font sizes -->22sp18sp15sp12sp<!-- typical spacing between two views -->40dp24dp14dp10dp4dp<!-- typical sizes of views -->60dp40dp32dp
布局時(shí)在寫margins和paddings時(shí)迹恐,你應(yīng)該使用spacing_xx尺寸格式來布局挣惰,而不是像對(duì)待string字符串一樣直接寫值,像這樣規(guī)范的尺寸很容易修改或重構(gòu)殴边,會(huì)使應(yīng)用所有用到的尺寸一目了然憎茂。 這樣寫會(huì)非常有感覺,會(huì)使組織和改變風(fēng)格或布局非常容易锤岸。
5.6.3 strings.xml
<string>的name命名使用下劃線命名法竖幔,采用以下規(guī)則:{模塊名_}邏輯名稱,這樣方便同一個(gè)界面的所有string都放到一起是偷,方便查找拳氢。
名稱說明
main_menu_about主菜單按鍵文字
friend_title好友模塊標(biāo)題欄
friend_dialog_del好友刪除提示
login_check_email登錄驗(yàn)證
dialog_title彈出框標(biāo)題
button_ok確認(rèn)鍵
loading加載文字
5.6.4 styles.xml
<style>的name命名使用大駝峰命名法,幾乎每個(gè)項(xiàng)目都需要適當(dāng)?shù)氖褂胹tyles.xml文件蛋铆,因?yàn)閷?duì)于一個(gè)視圖來說馋评,有一個(gè)重復(fù)的外觀是很常見的,將所有的外觀細(xì)節(jié)屬性(colors刺啦、padding留特、font)放在styles.xml文件中。 在應(yīng)用中對(duì)于大多數(shù)文本內(nèi)容,最起碼你應(yīng)該有一個(gè)通用的styles.xml文件蜕青,例如:
@dimen/font_normal@color/basic_black
應(yīng)用到TextView中:
或許你需要為按鈕控件做同樣的事情苟蹈,不要停止在那里,將一組相關(guān)的和重復(fù)android:xxxx的屬性放到一個(gè)通用的<style>中右核。
5.7 id 命名
命名規(guī)則:view縮寫{_模塊名}_邏輯名汉操,例如:btn_main_search、btn_back蒙兰。
如果在項(xiàng)目中有用黃油刀的話,使用 AS 的插件:ButterKnife Zelezny芒篷,可以非常方便幫助你生成注解搜变;沒用黃油刀的話可以使用 Android Code Generator 插件。
6 版本統(tǒng)一規(guī)范
Android 開發(fā)存在著眾多版本的不同针炉,比如compileSdkVersion挠他、minSdkVersion、targetSdkVersion以及項(xiàng)目中依賴第三方庫的版本篡帕,不同的 module 及不同的開發(fā)人員都有不同的版本殖侵,所以需要一個(gè)統(tǒng)一版本規(guī)范的文件。
具體可以參考我寫的這篇博文:Android 開發(fā)之版本統(tǒng)一規(guī)范镰烧。
如果是開發(fā)多個(gè)系統(tǒng)級(jí)別的應(yīng)用拢军,當(dāng)多個(gè)應(yīng)用同時(shí)用到相同的so庫時(shí),一定要確保so庫的版本一致怔鳖,否則可能會(huì)引發(fā)應(yīng)用崩潰茉唉。
7 第三方庫規(guī)范
別再閉門造車了,用用最新最火的技術(shù)吧结执,安利一波:Android 流行框架查速表度陆,順便帶上自己的干貨:Android 開發(fā)人員不得不收集的代碼。
希望 Team 能用時(shí)下較新的技術(shù)献幔,對(duì)開源庫的選取懂傀,一般都需要選擇比較穩(wěn)定的版本,作者在維護(hù)的項(xiàng)目蜡感,要考慮作者對(duì) issue 的解決蹬蚁,以及開發(fā)者的知名度等各方面。選取之后铸敏,一定的封裝是必要的缚忧。
個(gè)人推薦 Team 可使用如下優(yōu)秀輪子:
Dagger2(選用)
Tinker(選用)
8 注釋規(guī)范
為了減少他人閱讀你代碼的痛苦值,請(qǐng)?jiān)陉P(guān)鍵地方做好注釋杈笔。
8.1 類注釋
每個(gè)類完成后應(yīng)該有作者姓名和聯(lián)系方式的注釋闪水,對(duì)自己的代碼負(fù)責(zé)。
/**
* <pre>
*? ? author : Blankj
*? ? e-mail : xxx@xx
*? ? time? : 2017/03/07
*? ? desc? : xxxx 描述
*? ? version: 1.0
* </pre>
*/publicclassWelcomeActivity{? ? ...}
具體可以在 AS 中自己配制,進(jìn)入 Settings -> Editor -> File and Code Templates -> Includes -> File Header球榆,輸入
/**
* <pre>
*? ? author : ${USER}
*? ? e-mail : xxx@xx
*? ? time? : ${YEAR}/${MONTH}/${DAY}
*? ? desc? :
*? ? version: 1.0
* </pre>
*/
這樣便可在每次新建類的時(shí)候自動(dòng)加上該頭注釋朽肥。
8.2 方法注釋
每一個(gè)成員方法(包括自定義成員方法、覆蓋方法持钉、屬性方法)的方法頭都必須做方法頭注釋衡招,在方法前一行輸入/** + 回車或者設(shè)置Fix doc comment(Settings -> Keymap -> Fix doc comment)快捷鍵,AS 便會(huì)幫你生成模板每强,我們只需要補(bǔ)全參數(shù)即可始腾,如下所示。
/** * bitmap 轉(zhuǎn) byteArr * *@parambitmap bitmap 對(duì)象 *@paramformat 格式 *@return字節(jié)數(shù)組 */publicstaticbyte[] bitmap2Bytes(Bitmap bitmap, CompressFormat format) {if(bitmap ==null)returnnull;? ? ByteArrayOutputStream baos =newByteArrayOutputStream();? ? bitmap.compress(format,100, baos);returnbaos.toByteArray();}
8.3 塊注釋
塊注釋與其周圍的代碼在同一縮進(jìn)級(jí)別空执。它們可以是/* ... */風(fēng)格浪箭,也可以是// ...風(fēng)格(//后最好帶一個(gè)空格)。對(duì)于多行的/* ... */注釋辨绊,后續(xù)行必須從*開始奶栖, 并且與前一行的*對(duì)齊。以下示例注釋都是 OK 的门坷。
/*
* This is
* okay.
*/// And so// is this./* Or you can
* even do this. */
注釋不要封閉在由星號(hào)或其它字符繪制的框架里宣鄙。
Tip:在寫多行注釋時(shí),如果你希望在必要時(shí)能重新?lián)Q行(即注釋像段落風(fēng)格一樣)默蚌,那么使用/* ... */冻晤。
8.4 其他一些注釋
AS 已幫你集成了一些注釋模板,我們只需要直接使用即可敏簿,在代碼中輸入todo明也、fixme等這些注釋模板,回車后便會(huì)出現(xiàn)如下注釋惯裕。
//TODO:17/3/14 需要實(shí)現(xiàn)温数,但目前還未實(shí)現(xiàn)的功能的說明//FIXME:17/3/14 需要修正,甚至代碼是錯(cuò)誤的蜻势,不能工作撑刺,需要修復(fù)的說明
9 測(cè)試規(guī)范
業(yè)務(wù)開發(fā)完成之后,開發(fā)人員做單元測(cè)試握玛,單元測(cè)試完成之后够傍,保證單元測(cè)試全部通過,同時(shí)單元測(cè)試代碼覆蓋率達(dá)到一定程度(這個(gè)需要開發(fā)和測(cè)試約定挠铲,理論上越高越好)冕屯,開發(fā)提測(cè)。
9.1 單元測(cè)試
測(cè)試類的名稱應(yīng)該是所測(cè)試類的名稱加Test拂苹,我們創(chuàng)建DatabaseHelper的測(cè)試類安聘,其名應(yīng)該叫DatabaseHelperTest。
測(cè)試函數(shù)被@Test所注解,函數(shù)名通常以被測(cè)試的方法為前綴浴韭,然后跟隨是前提條件和預(yù)期的結(jié)果丘喻。
模板:void methodName前提條件和預(yù)期結(jié)果()
例子:void signInWithEmptyEmailFails()
注意:如果函數(shù)足夠清晰,那么前提條件和預(yù)期的結(jié)果是可以省略的念颈。
有時(shí)一個(gè)類可能包含大量的方法泉粉,同時(shí)需要對(duì)每個(gè)方法進(jìn)行幾次測(cè)試。在這種情況下榴芳,建議將測(cè)試類分成多個(gè)類嗡靡。例如,如果DataManager包含很多方法窟感,我們可能要把它分成DataManagerSignInTest叽躯、DataManagerLoadUsersTest等等。
9.2 Espresso 測(cè)試
每個(gè) Espresso 測(cè)試通常是針對(duì)Activity肌括,所以其測(cè)試名就是其被測(cè)的Activity的名稱加Test,比如SignInActivityTest酣难。
10 其他的一些規(guī)范
合理布局谍夭,有效運(yùn)用<merge>、<ViewStub>憨募、<include>標(biāo)簽紧索;
Activity和Fragment里面有許多重復(fù)的操作以及操作步驟,所以我們都需要提供一個(gè)BaseActivity和BaseFragment菜谣,讓所有的Activity和Fragment都繼承這個(gè)基類珠漂。
方法基本上都按照調(diào)用的先后順序在各自區(qū)塊中排列;
相關(guān)功能作為小區(qū)塊放在一起(或者封裝掉)尾膊;
當(dāng)一個(gè)類有多個(gè)構(gòu)造函數(shù)媳危,或是多個(gè)同名函數(shù),這些函數(shù)應(yīng)該按順序出現(xiàn)在一起冈敛,中間不要放進(jìn)其它函數(shù)待笑;
數(shù)據(jù)提供統(tǒng)一的入口。無論是在 MVP抓谴、MVC 還是 MVVM 中暮蹂,提供一個(gè)統(tǒng)一的數(shù)據(jù)入口,都可以讓代碼變得更加易于維護(hù)癌压。比如可使用一個(gè)DataManager仰泻,把http、preference滩届、eventpost集侯、database都放在DataManager里面進(jìn)行操作,我們只需要與DataManager打交道;
多用組合浅悉,少用繼承趟据;
提取方法,去除重復(fù)代碼术健。對(duì)于必要的工具類抽取也很重要汹碱,這在以后的項(xiàng)目中是可以重用的。
可引入Dagger2減少模塊之間的耦合性荞估。Dagger2是一個(gè)依賴注入框架咳促,使用代碼自動(dòng)生成創(chuàng)建依賴關(guān)系需要的代碼。減少很多模板化的代碼勘伺,更易于測(cè)試跪腹,降低耦合,創(chuàng)建可復(fù)用可互換的模塊飞醉;
項(xiàng)目引入RxAndroid響應(yīng)式編程冲茸,可以極大的減少邏輯代碼;
通過引入事件總線缅帘,如:EventBus轴术、AndroidEventBus、RxBus钦无,它允許我們?cè)贒ataLayer中發(fā)送事件逗栽,以便ViewLayer中的多個(gè)組件都能夠訂閱到這些事件,減少回調(diào)失暂;
盡可能使用局部變量彼宠;
及時(shí)關(guān)閉流;
盡量減少對(duì)變量的重復(fù)計(jì)算弟塞;
如下面的操作:
for(inti =0; i < list.size(); i++) {? ? ? ...}
建議替換為:
for(inti =0, len = list.size(); i < len; i++) {? ? ? ...}
盡量采用懶加載的策略凭峡,即在需要的時(shí)候才創(chuàng)建;
例如:
String str ="aaa";if(i ==1) {? ? ? list.add(str);}
建議替換為:
if(i ==1) {? ? ? String str ="aaa";? ? ? list.add(str);}
不要在循環(huán)中使用try…catch…决记,應(yīng)該把其放在最外層想罕;
使用帶緩沖的輸入輸出流進(jìn)行 IO 操作;
盡量使用HashMap霉涨、ArrayList按价、StringBuilder,除非線程安全需要笙瑟,否則不推薦使用HashTable楼镐、Vector、StringBuffer往枷,后三者由于使用同步機(jī)制而導(dǎo)致了性能開銷框产;
盡量在合適的場(chǎng)合使用單例凄杯;
使用單例可以減輕加載的負(fù)擔(dān)、縮短加載的時(shí)間秉宿、提高加載的效率戒突,但并不是所有地方都適用于單例,簡(jiǎn)單來說描睦,單例主要適用于以下三個(gè)方面:
控制資源的使用膊存,通過線程同步來控制資源的并發(fā)訪問。
控制實(shí)例的產(chǎn)生忱叭,以達(dá)到節(jié)約資源的目的隔崎。
控制數(shù)據(jù)的共享,在不建立直接關(guān)聯(lián)的條件下韵丑,讓多個(gè)不相關(guān)的進(jìn)程或線程之間實(shí)現(xiàn)通信爵卒。
把一個(gè)基本數(shù)據(jù)類型轉(zhuǎn)為字符串,基本數(shù)據(jù)類型.toString()是最快的方式撵彻,String.valueOf(數(shù)據(jù))次之钓株,數(shù)據(jù) + ""最慢;
使用 AS 自帶的 Lint 來優(yōu)化代碼結(jié)構(gòu)(什么陌僵,你不會(huì)享幽?右鍵 module、目錄或者文件拾弃,選擇 Analyze -> Inspect Code);
最后不要忘了內(nèi)存泄漏的檢測(cè)摆霉;
最后啰嗦幾句:
好的命名規(guī)則能夠提高代碼質(zhì)量豪椿,使得新人加入項(xiàng)目的時(shí)候降低理解代碼的難度;
規(guī)矩終究是死的携栋,適合團(tuán)隊(duì)的才是最好的搭盾;
命名規(guī)范需要團(tuán)隊(duì)一起齊心協(xié)力來維護(hù)執(zhí)行,在團(tuán)隊(duì)生活里婉支,誰都不可能獨(dú)善其身鸯隅;
一開始可能會(huì)有些不習(xí)慣,持之以恒向挖,總會(huì)成功的蝌以。
附錄
UI 控件縮寫表
名稱縮寫
Buttonbtn
CheckBoxcb
EditTextet
FrameLayoutfl
GridViewgv
ImageButtonib
ImageViewiv
LinearLayoutll
ListViewlv
ProgressBarpb
RadioButtionrb
RecyclerViewrv
RelativeLayoutrl
ScrollViewsv
SeekBarsb
Spinnerspn
TextViewtv
ToggleButtontb
VideoViewvv
WebViewwv
常見的英文單詞縮寫表
名稱縮寫
averageavg
backgroundbg(主要用于布局和子布局的背景)
bufferbuf
controlctrl
currentcur
defaultdef
deletedel
documentdoc
errorerr
escapeesc
iconic(主要用在 App 的圖標(biāo))
incrementinc
informationinfo
initialinit
imageimg
InternationalizationI18N
lengthlen
librarylib
messagemsg
passwordpwd
positionpos
previouspre
selectorsel(主要用于某一 view 多種狀態(tài),不僅包括 ListView 中的 selector何之,還包括按鈕的 selector)
serversrv
stringstr
temporarytmp
windowwin
程序中使用單詞縮寫原則:不要用縮寫跟畅,除非該縮寫是約定俗成的。
參考
Project and code style guidelines
小細(xì)節(jié)溶推,大用途徊件,35 個(gè) Java 代碼性能優(yōu)化總結(jié)!
版本日志
17/12/05: 新增 logo;
17/12/04: 完善按功能分包墨技,修復(fù) typo钝尸,定該版為完結(jié)版;
17/12/03: 完善代碼樣式規(guī)范和測(cè)試規(guī)范部翘;
17/12/02: 新增代碼樣式規(guī)范硝训;
17/12/01: 對(duì)資源文件規(guī)范進(jìn)行重構(gòu);
17/11/29: 格式化中英混排略就;
17/03/14: 包名劃分為按功能劃分捎迫;
17/03/13: 新增其他注釋;
17/03/08: 規(guī)范排版表牢,修復(fù) typo 及新增一些規(guī)范窄绒;
17/03/07: 修訂目錄排版,完善某些細(xì)節(jié)崔兴;
17/03/06: 發(fā)布初版彰导;
作者:Blankj
鏈接:http://www.reibang.com/p/45c1675bec69
來源:簡(jiǎn)書
簡(jiǎn)書著作權(quán)歸作者所有,任何形式的轉(zhuǎn)載都請(qǐng)聯(lián)系作者獲得授權(quán)并注明出處敲茄。