開發規范:《阿里巴巴Android開發手冊》之初理解

今天一早就看見了《阿里巴巴Android開發手冊》開放下載的推送。該開發規范在阿里內部經過了長期的修繕,現已總結成冊,向所有移動開發者、技術愛好者開放,希望幫助開發者碼出高效、碼出質量,提升系統的質量、協作的高效性。粗略翻閱一遍后,總結出部分規范。日后再當細讀。下載地址:《阿里巴巴Android開發手冊》下載

前言

《阿里巴巴 Android 開發手冊》(以下簡稱《手冊》)是阿里各大 Android 開發團隊的集體智慧結晶和經驗總結,將多個 App 長期開發迭代和優化經驗系統地整理成冊,以指導 Android 開發者更加高效、高質量地進行 App 開發。共同遵循同一開發規范,既是高效合作的基礎,也是深度創新的開始。《手冊》遵循《阿里巴巴 Java 開發手冊》手冊下載地址:https://yq.aliyun.com/articles/693 。以java為開發語言,制定相應規范,對kotlin等并未涉及。目錄結構如下:

《阿里巴巴Android開發手冊》目錄

Android 資源文件命名與使用

《手冊》中推薦資源命名時增加模塊前綴,以此區分,方便查找。drawable 資源名稱以小寫單詞+下劃線的方式命名,根據分辨率不同存放在不同的 drawable 目錄下,建議只使用一套,例如 drawable-xhdpi。大分辨率圖片(單維度超過 1000)大分辨率圖片建議統一放在 xxhdpi 目錄下管理,否則將導致占用內存成倍數增加。

Android 基本組件

Android 基本組件指 Activity、Fragment、Service、BroadcastReceiver、ContentProvider 等。《手冊》進行了17點講解,大致可以從3個角度來進行理解。

從代碼嚴謹度來考慮:

以下幾點都為了減少bug,因此都為強制:

  • Activity 間的數據通信,數據量較大時,避免使用 Intent + Parcelable的方式,可以考慮 EventBus 等替代方案,以免造成 TransactionTooLargeException。
  • Activity 間通過隱式 Intent 的跳轉,在發出 Intent 之前必須通過 resolveActivity檢查,避免找不到合適的調用組件,造成 ActivityNotFoundException 的異常。
  • 避免在 Service#onStartCommand()/onBind()方法中執行耗時操作,如果確實有需求,應改用 IntentService 或采用其他異步機制完成。
  • 避免在 BroadcastReceiver#onReceive()中執行耗時操作,如果有耗時工作,應該創建 IntentService 完成,而不應該在 BroadcastReceiver 內創建子線程去做。
  • 不要在 Android 的 Application 對象中緩存數據。基礎組件之間的數據共享請使用 Intent 等機制,也可使用 SharedPreferences 等數據持久化機制。
  • 使用 Adapter 的時候,如果你使用了 ViewHolder 做緩存,在 getView()的方法中無論這項 convertView 的每個子控件是否需要設置屬性(比如某個 TextView設置的文本可能為 null,某個按鈕的背景色為透明,某控件的顏色為透明等),都需要為其顯式設置屬性(Textview 的文本為空也需要設置 setText(""),背景透明也需要設置),否則在滑動的過程中,因為 adapter item 復用的原因,會出現內容的顯示錯亂。
  • Activity或者 Fragment 中動態注冊BroadCastReceiver 時,registerReceiver()和 unregisterReceiver()要成對出現。
    說明:如果 registerReceiver()和 unregisterReceiver()不成對出現,則可能導致已經注冊的receiver 沒有在合適的時機注銷,導致內存泄漏,占用內存空間,加重 SystemService負擔。部分華為的機型會對 receiver 進行資源管控,單個應用注冊過多 receiver 會觸發管控模塊拋出異常,應用直接崩潰。

從性能考慮:

  • 如非必須,避免使用嵌套的 Fragment。
  • 當前Activity的onPause方法執行結束后才會執行下一個Activity的onCreate方法,所以在 onPause 方法中不適合做耗時較長的工作,這會影響到頁面之間的跳轉效率。
  • 對于只用于應用內的廣播,優先使用 LocalBroadcastManager 來進行注冊和發送,LocalBroadcastManager 安全性更好,同時擁有更高的運行效率。說明:對于使用 Context#sendBroadcast()等方法發送全局廣播的代碼進行提示。如果該廣播僅用于應用內,則可以使用 LocalBroadcastManager 來避免廣播泄漏以及廣播被攔截等安全問題,同時相對全局廣播本地廣播的更高效。
  • Service 需要以多線程來并發處理多個啟動請求,建議使用 IntentService,可避免各種復雜的設置。說明:Service 組件一般運行主線程,應當避免耗時操作,如果有耗時操作應該在 Worker線程執行。 可以使用 IntentService 執行后臺任務。
  • 總是使用顯式 Intent 啟動或者綁定 Service,且不要為服務聲明 Intent Filter,保證應用的安全性。如果確實需要使用隱式調用,則可為 Service 提供 Intent Filter并從 Intent 中排除相應的組件名稱,但必須搭配使用 Intent#setPackage()方法設置Intent 的指定包名,這樣可以充分消除目標服務的不確定性。
  • 不要在 Activity#onDestroy()內執行釋放資源的工作,例如一些工作線程的銷毀和停止,因為 onDestroy()執行的時機可能較晚。可根據實際需要,在Activity#onPause()/onStop()中結合 isFinishing()的判斷來執行。
  • 添 加 Fragment 時 , 確 保 FragmentTransaction#commit() 在Activity#onPostResume()或者 FragmentActivity#onResumeFragments()內調用。不要隨意使用 FragmentTransaction#commitAllowingStateLoss()來代替,任何commitAllowingStateLoss()的使用必須經過 code review,確保無負面影響。
  • Activity#onSaveInstanceState()方法不是 Activity 生命周期方法,也不保證一定會被調用。它是用來在 Activity 被意外銷毀時保存 UI 狀態的,只能用于保存臨時性數據,例如 UI 控件的屬性等,不能跟數據的持久化存儲混為一談。持久化存儲應該在 Activity#onPause()/onStop()中實行。

從用戶體驗考慮:

  • 使用 Toast 時,建議定義一個全局的 Toast 對象,這樣可以避免連續顯示Toast 時不能取消上一次 Toast 消息的情況(如果你有連續彈出 Toast 的情況,避免使用 Toast.makeText)

UI 與布局:

這部分內容主要是一些基礎規范,比如靈活使用布局,推薦 Merge、ViewStub 來優化布局,盡可能多的減少 UI
布局層級,推薦使用 FrameLayout,LinearLayout、RelativeLayout 次之。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。