天天看點

谷歌官方推出Android應用開發架構元件介紹(Android Architecture Components)

簡評:雖然說 Android 的架構選擇一直都很自由,MVP、MVC、MVVM 各有擁趸。但 Google 最近還是推出了一份關于應用架構的實踐指南,并給出了相當詳盡的步驟和一些指導建議。希望大家都能看一看,學習一下,打造更加優秀易用的 APP,也為 Android 生态的改善做一點貢獻。: )

今年,官方在I/O 2017開發者大會上推出了Android開發的官方架構和最佳實踐指南。這裡就給大家介紹一下:

架構元件(Android Architecture Components) 是 2017 Google IO 上釋出的關于安卓開發的一個重量級架構。算是安卓開發架構的一個官方參考實作。現在該架構還處于 alpha1 版本,估計會在 Android O 正式釋出的時候一起釋出。

官方位址:https://developer.android.google.cn/topic/libraries/architecture/index.html

官方最新架構原則

首先,Android 開發者肯定都知道 Android 中有四大元件,這些元件都有各自的生命周期并且在一定程度上是不受你控制的。在任何時候,Android 作業系統都可能根據使用者的行為或資源緊張等原因回收掉這些元件。

這也就引出了第一條準則:「不要在應用程式元件中儲存任何應用資料或狀态,并且元件間也不應該互相依賴」。

最常見的錯誤就是在 Activity 或 Fragment 中寫了與 UI 和互動無關的代碼。盡可能減少對它們的依賴,這能避免大量生命周期導緻的問題,以提供更好的使用者體驗。

第二條準則:「通過 model 驅動應用 UI,并盡可能的持久化」。

這樣做主要有兩個原因:

  1.  如果系統回收了你的應用資源或其他什麼意外情況,不會導緻使用者丢失資料。
  2.  Model 就應該是負責處理應用程式資料的元件。獨立于視圖和應用程式元件,保持了視圖代碼的簡單,也讓你的應用邏輯更容易管理。并且,将應用資料置于 model 類中,也更有利于測試。

官方架構元件

基礎上面兩個最新的架構原則,Android官方推出了一些的架構元件:

架構元件是多個小庫組成的。你可以隻使用其中的一部分也可以使用所有的庫,目前由下面幾個庫共同組成安卓架構元件庫:

  • android.arch.core:core 包含一個自定義的 Function 接口和幾個内部用到的類
  • android.arch.core:core-testing 用于測試的一個核心類, 依賴于上面的 core 庫
  • android.arch.lifecycle:common 生命周期庫的通用接口,裡面定義了幾個管理生命周期的一些接口,有 Lifecycle、LifecycleObserver、LifecycleOwner、OnLifecycleEvent、ViewModel、ViewModelProvider、ViewModelStore、ViewModelStoreOwner 等類和接口。
  • android.arch.lifecycle:runtime 庫定義了幾個生命周期相關的運作時接口,這個庫依賴 android.arch.core:core 和 android.arch.lifecycle:common 庫。裡面有LifecycleRegistry、ProcessLifecycleOwner、ServiceLifecycleDispatcher、LifecycleActivity、LifecycleFragment、LifecycleService 等接口。值得注意的是, LifecycleActivity 是繼承至 android.support.v4.app.FragmentActivity 的,而 LifecycleFragment 是繼承至 android.support.v4.app.Fragment 的,當 android.arch.lifecycle 正式釋出的時候,這兩個類将被删除,Support v4 中的 FragmentActivity 和 Fragment 将直接實作 LifecycleRegistryOwner 接口。也就是說,當安卓架構元件正式釋出的時候, 新版本的 Support v4庫将依賴架構庫并提供基本的實作。如果你不使用安卓架構元件的話,對你的影響也不大,隻是添加了幾個接口和十幾個函數而已。
  • android.arch.lifecycle:extensions  這個庫依賴前面的 runtime 庫,裡面是擴充生命周期功能的幾個接口定義和實作,主要有 AndroidViewModel 接口,裡面可以通路 Application context 對象;LiveData 的類,使用者在生命周期中儲存資料的;Transformations 助手類實作簡單的資料處理操作,類似 RxJava 中的操作符;ViewModelProviders 提供了對 ViewModel 的建立和管理。
  • android.arch.lifecycle:compiler 這個是用來生成代碼的庫,需要使用 annotationProcessor “android.arch.lifecycle:compiler:1.0.0-alpha1” 的方式來引用,自動生成一些代碼避免使用反射來提高性能。
  • android.arch.persistence.room 是資料庫 ORM 架構,裡面包含了 common、runtime、migration、support-db、support-db-impl、compiler 等子庫。如果你的應用中不使用 Sqlite 則無需使用 room 架構。

從上面的庫分布可以看到,安卓架構元件的主要功能有兩個:管理生命周期和資料庫 ORM 。

生命周期

生命周期是 Android 應用中的特點,Android 系統四大元件都有不同的生命周期,系統會在不同的時候調用這些生命周期回調接口,你一個應用需要恰當的處理這些生命周期回調接口,否則的話您的應用可能會導緻記憶體洩露或者應用會崩潰。對于 Android 開發新手來說,處理這些生命周期是比較麻煩的,是以 Android 團隊希望通過這個 lifecycle 庫來幫助開發者正确的處理生命周期。

ViewModel 是幹什麼的呢?

ViewModel 是生命周期中延伸出來的一個概念,比如 Activity,一般而言我們會把很多代碼都放到 Activity 中去,但是 Activity 類是系統調用的,系統會在不同的情況下去調用 Activity 的不同函數,Activity 類隻是系統和您的應用的橋梁,是以避免把過多的代碼放到 Activity 中去,官方建議隻有 處理 UI 事件或者和系統服務互動的代碼才能放到 Activity 中。

另外你的 UI 應該有模型(model)來驅動,模型的責任是處理應用的資料,和 View 以及你 App 中的其他元件是獨立的,并且模型應該和生命周期分離。這樣 UI 代碼盡可能的簡單并和 App 邏輯代碼分離可以很友善的處理生命周期的變化。

是以 ViewModel 的出現是為了簡化生命周期處理的,如果你有資料需要在 Activity 中顯示,則可以把資料定義到 ViewModel 中,通過 ViewModel 來管理和存儲 UI 相關的資料,這樣當 Activity 配置改變的時候您的資料依然存在,比如 當螢幕從橫屏變為豎屏,你目前 Activity 的資料依然存在。

LiveData 

把資料儲存到 ViewModel 中就可以保持資料在配置改變的時候依然存在,但是如果資料發生變化了,我們如何通知 UI 去更新界面呢?如果 資料是來至于其他地方的并且請求資料需要消耗資源,如果確定隻有在對使用者有意義的生命周期階段才執行請求資料的操作呢?這個時候就需要 LiveData 了。

LiveData 是用來儲存資料的,裡面可以儲存一個資料對象并且該資料是可以被檢測的同時 LiveData 的 Live 說明 LiveData 會自動處理生命周期事件,隻有當 Lifecycle 處于 STARTED 或者 RESUMED 狀态的時候才認為是活動狀态。比如你在請求一個圖檔,如果使用者點選傳回鍵退出了應用,則 LiveData 處于非活動狀态,這個時候你就可以取消繼續請求圖檔的操作了。

是以 LiveData 和 ViewModel 是 Lifecycle 的有利補充。

    LiveData 是一個可被觀察的資料持有者(用到了觀察者模式)。其能夠允許 Activity, Fragment 等應用程式元件對其進行觀察,并且不會在它們之間建立強依賴。LiveData 還能夠自動響應各元件的聲明周期事件,防止記憶體洩漏,進而使應用程式不會消耗更多的記憶體。

    注意:LiveData 和 RxJava 或 Agera 的差別主要在于 LiveData 自動幫助處理了生命周期事件,避免了記憶體洩漏。

資料持久化

不支援離線的應用不是一個使用者體驗良好的應用,使用者手機網絡的變化是不可預知的,特别是現在複雜的社會環境,比如做地鐵到地下隧道了,手機沒信号了,這個時候你正在浏覽微網誌,看到一個有趣的消息想去點贊,點了一個贊微網誌應用就在哪裡轉圈,阻止你去看其他資訊。一直等到出隧道恢複信号了才能點贊成功。如果你在隧道的時間比較長,則你一定感覺不爽。 如果應用支援離線使用,點贊的時候,應用把點贊的操作持久化到本地,然後你還可以繼續浏覽其他本地已經緩存的消息,當手機恢複網絡的時候,應用自動把之前的點贊操作同步到伺服器,這種體驗肯定要好很多。

是以資料持久化是一個比較重要的功能,要儲存複雜的資料在 Android 上沒有比 Sqlite 更好的方式了。而使用 Sqlite 要求大家了解 Sql 語句并且手寫各種建立表和查詢表的 Sql 語句,這是比較繁瑣的一項任務。而 Java 早在 2001 年就出現 Hibernate 等 ORM 架構了,但是這些 ORM 架構都比較“笨重” 無法在 Android 環境下使用, 近幾年也出現了一些 Android 上的 ORM 架構比如 GreenDao、Ormlite 等,而來自官方的 Room 架構風格上有點借鑒 Retrofit 的意思,也算是官方提供的一個 ORM 架構了。如果你的應用需要儲存資料,則可以考慮下 Room 架構。

Room

    Room 能幫助我們友善的實作本地資料持久化,抽象出了很多常用的資料庫操作,并且在編譯時會驗證每個查詢,進而損壞的 SQL 查詢隻會導緻編譯時錯誤,而不是運作時崩潰。還能和上面介紹的 LiveData 完美合作,并幫開發者處理了很多線程問題。

官方推薦的 App 架構

最後的架構一圖以概之看起來就像這樣:

谷歌官方推出Android應用開發架構元件介紹(Android Architecture Components)

最後的最後,給出一些指導原則

下面的原則雖然不是強制性的,但根據我們的經驗遵循它們能使您的代碼更健壯、可測試和可維護的。

  • 所有您在 manifest 中定義的元件 - activity, service, broadcast receiver... 都不是資料源。因為每個元件的生命周期都相當短,并取決于目前使用者與裝置的互動和系統的運作狀況。簡單來說,這些元件都不應當作為應用的資料源。
  • 在您應用的各個子產品之間建立明确的責任邊界。比如,不要将與資料緩存無關的代碼放在同一個類中。
  • 每個子產品盡可能少的暴露内部實作。從過去的經驗來看,千萬不要為了一時的友善而直接将大量的内部實作暴露出去。這會讓你在以後承擔很重的技術債務(很難更換新技術)。
  • 在您定義子產品間互動時,請考慮如何使每個子產品盡量隔離,通過設計良好的 API 來進行互動。
  • 您應用的核心應該是能讓它脫穎而出的某些東西。不要浪費時間重複造輪子或一次次編寫同樣的模闆代碼。相反,應當集中精力在使您的應用獨一無二,而将一些重複的工作交給這裡介紹的 Android Architecture Components 或其他優秀的庫。
  • 盡可能持久化資料,以便您的應用在脫機模式下依然可用。雖然您可能享受着快捷的網絡,但您的使用者可能不會。

本文不再貼相關代碼,具體各個庫的使用請檢視官方文檔:https://developer.android.com/topic/libraries/architecture/guide.html

附上官方的DEMO項目:https://github.com/googlesamples/android-architecture-components

繼續閱讀