Android Architecture Components架構下的高效開發
概述
Android Architecture Components是一系列庫集合,能幫助你設計出健壯的,可測試的,可維護的應用。使用幾個類,來管理UI元件的生命週期和處理資料持久化。
-
管理app的生命週期很輕鬆。新的 lifecycle-aware components 元件,能幫助你管理activity/fragment的生命週期。儲存配置更改,避免記憶體洩漏並輕鬆載入資料。
-
使用LiveData構建資料物件,在底層資料庫更改時通知檢視。
-
ViewModel儲存UI相關資料,這些資料不會在應用旋轉中被銷燬。
-
Room是一個SQLite物件對映庫。使用它避免樣板程式碼,並容易地將SQLite表資料轉換為Java物件。提供SQLite語句的編譯時檢查,並可以返回RxJava,Flowable和LiveData可觀察物件。
架構圖
推薦使用官方架構,模組的互動方式如下:

Picture
生命週期感知元件
感知生命週期的元件執行動作,以響應其他元件(如Activity和Fragment)的生命週期狀態的變化。這些元件有助於產生更好的組織性和更輕的重量程式碼,這更易於維護。
一種常見的模式是在Activity和Fragment的生命週期方法中實現依賴元件的動作。然而,這種模式導致程式碼的組織和錯誤擴散。通過使用生命週期感知元件,可以將依賴元件的程式碼從生命週期方法中移出並移入元件本身。
生命週期包提供了允許您構建生命週期感知元件的類和介面,這些元件可以根據Activity和Fragment的當前生命週期狀態自動調整它們的行為。
Lifecycle-Aware Components,主要包含三個基本介面:
- LifecycleOwner
interface LifecycleOwner {
getLifecycle();
}
在FragmentActivity和Fragment實現,返回Lifecycle物件,用來給外部管理生命週期狀態。
- Lifecycle
Lifecycle物件,能觀察LifecycleObserver物件,並返回當前LifecycleOwner的生命週期狀態(started,created)。
- LifecycleObserver
實現LifecycleObserver的類,能通過註解的方式,接收到狀態變化的通知。如:
@OnLifecycleEvent(Lifecycle.Event.ON_CREATE) void onCreate(LifecycleOwner lifecycleOwner) { } @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) void onResume(LifecycleOwner lifecycleOwner) { }
比如,ViewModel類實現了LifecycleObserver介面,在Activity裡新增getLifecycle().addObserver(viewModel);
那ViewModel就有了生命週期感知功能。
在Android框架中定義的大多數應用程式元件都有生命週期。生命週期是由作業系統或執行在您的程序中的框架程式碼管理的。它們是Android工作的核心,你的應用程式必須尊重它們。不這樣做可能觸發記憶體洩漏或甚至應用崩潰。
想象一下,我們有一個Activity顯示螢幕上的裝置位置。一個常見的實現方式可能如下:
class MyActivity extends AppCompatActivity { private MyLocationListener myLocationListener; public void onCreate(...) { myLocationListener = new MyLocationListener(this, location -> { // update UI }); } @Override public void onStart() { super.onStart(); Util.checkUserStatus(result -> { // what if this callback is invoked AFTER activity is stopped? if (result) { myLocationListener.start(); } }); } @Override public void onStop() { super.onStop(); myLocationListener.stop(); } }
用了Lifecycle,還可以這樣:
public class MyObserver implements LifecycleObserver { @OnLifecycleEvent(Lifecycle.Event.ON_RESUME) public void connectListener() { ... } @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE) public void disconnectListener() { ... } } myLifecycleOwner.getLifecycle().addObserver(new MyObserver());
是不是清晰很多。
LiveData
LiveData是一個可觀測的資料保持類。與常規觀察不同,LiveData是生命週期感知的,這意味著它尊重其他應用程式元件(如Activity、Fragment或Service)的生命週期。這種感知確保LiveData只更新處於 活躍生命週期 狀態的應用程式元件觀察者。
您可以註冊一個與實現 LifecycleOwner
介面的物件配對的觀察者。這種關係允許當相應 ([ https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.html)[|](https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.html)[%7C)60d8d77e15b1b69c7a3cfbc6b952b9393 |]物件的狀態改變為([ https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.State.html#DESTROYED)[|](https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.State.html#DESTROYED)[| ) 60d8d77e15b1b69c7a3cfbc6b952b9394 |]時觀察者被移除。這對於Activity和Fragment尤其有用,因為它們可以安全地觀察 ([ https://developer.android.google.cn/reference/android/arch/lifecycle/LiveData.html ) | [%7C)60d8d77e15b1b69c7a3cfbc6b952b9395 |]物件,而不用擔心洩漏——當Activity或Fragment的生命週期被銷燬時,它們會立即取消訂閱。
有關如何使用LiveData的更多資訊,請參見 使用LiveData物件 。
使用LiveData的優勢
-
確保UI與資料狀態匹配
LiveData遵循觀察者模式。當生命週期狀態改變時,LiveData通知觀察者物件。您可以合併程式碼來更新這些觀察物件中的UI。每次應用程式資料更改時,都不更新UI,觀察者可以每次更改時更新UI。
-
沒有記憶體洩漏
觀察者繫結到生命週期物件,並在其關聯的生命週期被銷燬後自行清理。
-
停止Activity時的崩潰
如果觀察者的生命週期是不活動的,比如在後堆疊中的活動,那麼它不接收任何LiveData事件。
-
無需手動處理生命週期
UI元件只是觀察相關資料,不停止或恢復觀察。LiveData自動管理所有這一切,因為它意識到相關的生命週期狀態變化,同時觀察。
-
始終保持最新資料
如果生命週期變得不活動,則在再次啟用時接收最新資料。例如,後臺中的Activity在返回到前臺後立即接收最新資料。
-
正確的配置改變
如果由於配置改變而重新生成Activity或Fragment,例如裝置旋轉,則它立即接收最新可用資料。
-
資源共享
您可以使用Sigelon模式擴充套件LiveData物件來包裝系統服務,以便它們可以在您的應用程式中共享。LiveData物件連線到系統服務一次,然後需要該資源的任何觀察者都可以只觀察LiveData物件。有關更多資訊,請參見 擴充套件LiveData 。
如何使用LiveData
按照以下步驟使用LiveData物件:
-
建立一個LiveData例項來儲存某種型別的資料。這通常是在ViewModel類中完成的。
-
建立一個Observer物件,該物件定義onChanged()方法,該方法控制LiveData物件儲存的資料更改時發生的情況。通常在UI控制器,例如Activity或Fragment中,建立一個Observer物件。
-
使用
observe()
60d8d77e15b1b69c7a3cfbc6b952b93910 |]方法傳入([ https://developer.android.google.cn/reference/android/arch/lifecycle/LifecycleOwner.html ) | [%7C)60d8d77e15b1b69c7a3cfbc6b952b93911 |]物件。這將觀察物件向LiveData物件訂閱,以便通知其更改。通常將觀察者物件附加在UI控制器中,例如Activity或Fragment。 -
當更新LiveData物件中儲存的值時,只要所附的LifecycleOwner處於活動狀態,就會觸發所有已註冊的觀察器。
LiveData允許UI控制器觀察員訂閱更新。當LiveData物件儲存的資料發生變化時,UI會自動響應更新。
建立LiveData
public class NameViewModel extends ViewModel { // Create a LiveData with a String private MutableLiveData<String> mCurrentName; public MutableLiveData<String> getCurrentName() { if (mCurrentName == null) { mCurrentName = new MutableLiveData<String>(); } return mCurrentName; } // Rest of the ViewModel... }
觀察LiveData
public class NameActivity extends AppCompatActivity { private NameViewModel mModel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Other code to setup the activity... // Get the ViewModel. mModel = ViewModelProviders.of(this).get(NameViewModel.class); // Create the observer which updates the UI. final Observer<String> nameObserver = new Observer<String>() { @Override public void onChanged(@Nullable final String newName) { // Update the UI, in this case, a TextView. mNameTextView.setText(newName); } }; // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer. mModel.getCurrentName().observe(this, nameObserver); } }
擴充套件LiveData
LiveData認為觀察者必須在有效狀態,無論是在 STARTED
或([ https://developer.android.google.cn/reference/android/arch/lifecycle/Lifecycle.State.html#RESUMED ) | [|) 60d8d77e15b1b69c7a3cfbc6b952b93914 |]狀態,可以用來做全域性資料共享,
下面的示例程式碼說明如何擴充套件LiveData類:
public class StockLiveData extends LiveData<BigDecimal> { private StockManager mStockManager; private SimplePriceListener mListener = new SimplePriceListener() { @Override public void onPriceChanged(BigDecimal price) { setValue(price); } }; public StockLiveData(String symbol) { mStockManager = new StockManager(symbol); } @Override protected void onActive() { mStockManager.requestPriceUpdates(mListener); } @Override protected void onInactive() { mStockManager.removeUpdates(mListener); } }
多種場景下的使用
Activity/Fragment
最基本的UI場景,只需要在Activity/Fragment呼叫observe()方法關注LiveData資料,即可。
需要注意的是,使用Activity/Fragment都是LifecycleOwner物件,需要哪個LifecycleOwner就看業務需要。
ViewHolder
比如在RecyclerView的ViewHolder裡面觀察LiveData,因為ViewHolder有快取機制,所以Observer跟item並不一對一。一般可以在初始化ViewHolder時,觀察LiveData,然後接收到資料變更,則修改item資料,並重修重新整理ui。這樣才能做到相容ViewHolder機制。
View/ViewGroup
如果View不涉及到銷燬(重建)的情況,也不需要理會Observer,否則,也要管理Observer的觀察和取消觀察。
UI元件以外
UI元件以外,需要用到observeForever()方法,此方法沒有生命週期感知,需要手動管理取消觀察。
ViewModel管理LiveData和全域性LiveData的區別
本質上沒有不同,主要在於資料本身生命週期的需要和共享的需要。
比如ViewModel的LiveData會隨著Activity/Fragment產生、共享和銷燬,而全域性的LiveData是跟隨程序或手動管理的。
LiveData的建立場景和觀察場景
LiveData能在任何地方,任何情況建立。
觀察場景可以在UI元件使用observe()/observeForever()方法,或其他非UI場景只能用observeForever()方法。
附言
以上為個人的經驗總結,不當之處歡迎討論,並持續優化。

image

image