以前一直看到網上各類各樣的開發規範,相對比之下也貼一下咱們公司本身的開發規範,寫的仍是有必定道理可言的,約束越嚴格,相對應的後期開發也就越輕鬆,代碼管理也愈加簡單java
重要:github或者其餘任何非公司倉庫不容許上傳與項目業務邏輯有關的代碼實現
下班走以前提交代碼到SVN,上班來以後第一件事更新SVN
SVN版本 1.7.9
svn 只容許上傳正式代碼,測試代碼本機留存。
SVN 上的代碼必須是完整可運行的. 提交代碼到 SVN 以前的重要步驟:
1. 本機運行 app並測試
2. 檢查 Local Changes 下面的 "Unversioned Files" 中時候含有未添加的文件
java版本[編輯]
不容許使用java8(即便用插件支持也不行), 只容許使用 java7 的部分語法(不容許使用 try-with-resources 特性)
使用類方法以前,請確保類方法存在(好比 String#isEmpty 方法在 java5 中就不存在),在提交代碼以前,先在 2.3 模擬器中測試。
註釋規範[編輯]
文件註釋(必需)格式以下:
/*
* User:Dong Jiang
* Introduction: 高德換乘路線詳情地圖
*/
基本原則[編輯]
*第一保證可讀性*(不可讀的代碼當即重寫),第二保證準確性,第三考慮效率
本身學習的時候造輪子,普通工做中就不用。然而,工做並非你專心學習的時機,專心學習的時機都在晚上和假期。
任務完成以後,檢查本身的代碼,一切參照標準 1
在檢查一個對象內容是否爲空以前,先檢查對象自己是否是null,通用對象應該使用工具方法檢測。
可能返回null 的方法使用註解進行聲明。
不要省略語句後面的括號 {}。包括循環語句與條件語句
不容許使用 System.exit(0) 來進行正常的退出操做。必定要使用前,拿出來討論。
不容許存在魔數,任何具備邏輯意義的常量(數字,字符串等等),都應先聲明後使用。
任何狀況下(if, while,do等等),都不容許省略大括號。
減小布局層數以及佈局複用:採用<merge> 優化佈局層數;動態加載View, 採用 ViewStub 避免一些不常常的視圖長期握住引用; 採用<include >來共享佈局。
內存流,網絡流,文件流,Cursor等資源及時關閉
避免建立沒必要要的對象
使用加強for循環時不能對集合自己進行操做,arraylist要手動循環(提早計算集合size),For循環裏邊不能夠定義變量以及try-catch
合理利用浮點數,能用整形類型就不用浮點型
列表儘可能使用recyclerview
try-catch不能夠隨便揮霍影響性能
不能夠打印堆棧,調試下除外
若是不須要被繼承,儘可能指定類的final修飾符
儘可能使用局部變量
不要隨意的使用stingA=StringB+StringC的寫法,有大量拼接操做的地方用StringBuilder 代替。
不要隨便使用static變量,常量除外(static final)
費時的資源操做,使用Application的Context
調用方法時,參數深度層級不能多於2
代碼format。
沒必要要的代碼不要,包括之前邏輯的代碼,測試代碼,等,保持代碼清潔。
在網絡和文件(要在子線程去操做)操做等費時的地方,回調方法中在調用getview,content以及其餘數據等activity相關資源的時候先調用isViewAttached
bitmap不用時,要及時回收,須要呈現到界面時用glide代替bitmap(網絡和本地),不要用networkimageview,若是不是顯示界面要及時recycle
TypedArray要及時recycle
沒有用到的文件類方法不要留在項目中,保持代碼清潔
e.printStackTrace();禁止有這種東西,有須要能夠在lesslog裏以開關的方式作
儘可能避免硬編碼 漢字放置到String中,其餘創建字段
presenter儘可能避免持有直接Activity的引用,能用回調或者新加方法的儘可能新增
儘量少的使用全局變量,例子:將類中使用一次的變量直接在使用處new出
if(){}else{........},禁止出現這種if裏沒有代碼的狀況
for循環前必定要判空
條件語句的條件部分不要產生反作用。
若是須要修改公用的部分,在羣裏說一聲
switch-case語句在default里加入break
嚴禁 import static xxx.*;,惟一的例外是使用枚舉。
時間單位統一使用毫秒
使用 PopupWindow 或者 Dialog 的時候,在 Activity 銷燬以前,必定要關閉 PopupWindow 或者 Dialog
日誌[編輯]
不要直接使用SDK內置的Log,使用項目統一包裝的類或者工具
若是沒有特殊要求,log的第一個參數始終應該是 this。靜態方法中,第一個參數應該是類名。
不容許用本身的名字做爲日誌 tag
協做[編輯]
不是本身定義的接口不要修改
協商定義的接口不要修改
final類(不管是本身定義的仍是別人定義的)不要修改要修改先協商
優先使用已存在的解決方案,不要重複造輪子。
定義樣式的時候,遵守約定的規範格式,不要另起爐竈。
不要隨意在公共庫裏面增長類或者修改方法,增長以前先明確是否已有現成的實現
多線程[編輯]
不要直接使用Thread,應該使用項目統一包裝的類或者工具
在涉及多線程的地方,都要考慮內存泄露和數據安全的風險
異常處理[編輯]
控制消化或者拋出異常的時機,不能肯定的時候拿出來一塊兒討論
解決bug的時候不能粗暴的捕獲一切異常,必需要定位到具體的異常級別
錯誤示例[編輯]
隨意的命名[編輯]
1. 改變了工程的前綴,隨意取名
<style name="CLL.Item.MainTitle">
<item name="android:textColor">@color/core_textColorPrimary</item>
<item name="android:textSize">@dimen/text_size_14</item>
</style>
2. 乾脆沒有前綴
<style name="DialogAnimation">
<item name="android:windowEnterAnimation">@anim/cll_dialog_fullscreen_enter</item>
<item name="android:windowExitAnimation">@anim/cll_dialog_fullscreen_exist</item>
</style>
<declare-styleable name="TagCloudView">
<attr name="tcvBackground" format="reference"/>
<attr name="tcvTextColor" format="color"/>
<attr name="tcvBorder" format="dimension"/>
</declare-styleable>android
暴露細節[編輯]
StationDetailPresenterImpl:
@Override
public void parseIntent(Intent intent) {
mRefer = KpiReferer.getRefer(intent);
mPolicy = KpiPolicy.getPolicy(intent);
if (mPolicy == null) {
mPolicy = new Policy();
}
mStationEntity = intent.getParcelableExtra(LineConstant.IntentConstant.INTENT_EXTRA_STATION_ENTITY);
getView().showStationName(mStationEntity.getStationName());
DestStationEntity destStation = intent.getParcelableExtra(TransitConstant.INTENT_EXTRA_SCHEME_DEST);
if (destStation != null) {
loadStationsFilterByDestStation(destStation);
} else {
loadStationDetail();
}
}
過分封裝[編輯]
1. 毫無心義的封裝
/**
* 獲取當前版本的啓動次數
*/
private static int getOpenCountInCurrentVersion(Context context) {
return CllPreference.getInstance(context).getOpenCountInCurrentVersion();
}
2. 混合基礎功能 與 業務功能。業務功能應該使用對象,而不是 util
//增長一條非默認地點
private static void addNonDefaultDestEntity(final DestEntity destEntity, Poi poi, TransitParam normalParam, @DestType.Type int destType) {
TransitParam transitParam = new TransitParam()
.transitDest(poi.getGeoPoint())
.destType(destType)
.destName(poi.getName())
.destTag(poi.getName()); //默認狀況下,destTag和destName相同
transitParam.getParams().copyFrom(normalParam.getParams());
TransitClientFactory.getInstance().addDest(transitParam, new OptionalParam(), new DataListener<DestAddData>() {
@Override
public void onDataResponse(DestAddData data) {
super.onDataResponse(data);
destEntity.setDestId(data.getDestId());
}
});
}git