官方文檔永遠是最好的學習資料:
Android Jectpack
Android Jetpack: LiveData 和 Lifecycle 介紹 | 中文教學視頻
Android Jetpack - ViewModel | 中文教學視頻
Android Jetpack Room | 中文教學視頻
深刻了解還需多看文檔和源碼。java
AAC (Android Architecture Components) 是谷歌推出的一套包含在 Jetpack 中的,幫助咱們構建穩健、可測試且易維護應用的組件庫,主要包括 Lifecycle、LiveData、ViewModel、Room、WorkManager 等一系列好用的工具。注意,AAC 並非一種新的架構,只是一套和架構相關的工具,能夠幫助你更加簡單高效的構建你想要的架構。android
MVC (Model-View-Controller)、MVP (Model-View-Presenter) 和 MVVM (Model-View-ViewModel) 在 Android 中的應用大概能夠歸納爲下圖(架構分層因人而異,這裏只是我本身的一些理解)
git
IView
和
IPresenter
之類的接口,而後 View 層和 Presenter 層相互持有對方的引用,這樣就存在不少問題,好比:
Activity
已經 onDestroy
,但並無被回收的場景MVVM 採用 View 層與 ViewModel 層的數據綁定的方式,View 層監聽相應的數據,並在數據變動時本身更改視圖,從而很好地解決了上述問題:github
View
的顯示可見 MVVM 更爲先進好用,實現 MVVM 的方法也有不少,而 AAC 就是爲 MVVM 而生的,經過 AAC 中的 LiveData
和 ViewModel
等組件,咱們能夠很容易地在 Android 上實現 MVVM。它的 Lifecycle 組件可讓咱們更有效的管理 app 內的各類生命週期,在配置變動時保存數據,避免內存泄漏,更方便地把數據加載到 UI 中;LiveData 用來構建一個能夠在數據變動時通知視圖的數據對象,且具備生命週期感知的能力;ViewModel 能夠存儲 UI 相關的數據,並保證在配置變動時不會丟失。數據庫
LiveData
是一個可觀察的數據持有類,並且它能夠感知其餘應用組件 (如 Activity
、Fragment
或 Service
) 的生命週期,這種感知可確保 LiveData
僅更新生命週期處於激活狀態(STARTED 和 RESUMED)的觀察者。它的主要優勢有:緩存
LiveData
的最新數據,數據預加載再也不須要考慮 View
的狀態Activity
和 Fragment
重建時也會收到通知(須要和 ViewModel
配合使用)簡單用法。假設咱們的 MainActivity
的視圖中有一個 Button
和一個 TextView
來實現一個簡單的計數器,還有一個計數值的 LiveData
。點擊 Button
會更新計數值,而 TextView
監聽該 LiveData
來更新本身。示例分析以下:網絡
public class MainActivity extends AppCompatActivity {
// 一、MutableLiveData 是什麼
private MutableLiveData<Integer> mLiveData = new MutableLiveData<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 初始化工做
// ...
mLiveData.setValue(0);
// 二、LiveData.observe() 的參數都是什麼意思
// public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
mLiveData.observe(this, new Observer<Integer>() {
@Override
public void onChanged(@Nullable final Integer count) {
// Update the UI, in this case, a TextView.
mTextView.setText(newName);
}
});
// 三、LiveData 的值怎麼更新
mButton.setOnClickListener(v -> mLiveData.setValue(mLiveData.getValue() + 1));
}
}
複製代碼
一、首先 LiveData
是一個抽象類,且 setValue
和 postValue
兩個更新 value 的方法都是 protected
的,而 MutableLiveData
繼承 LiveData
,重寫這兩個方法,並將訪問權限設置爲 public
;架構
二、public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
第一個參數 LifecycleOwner
是持有生命週期的對象,好比 Activity
和 Fragment
,可讓 LiveData
能夠感知它的生命週期,並在生命週期結束時將其移除,避免內存泄漏;第二個參數 Observer
是一個接口,它只有一個方法 void onChanged(T t)
,LiveData
會在數據更新時調用這個函數來通知 UI 層的觀察者。併發
三、setValue
和 postValue
兩個均可以更新 value,不一樣之處在於 setValue
只能在主線程調用,而 postValue
能夠用於子線程(注意:短期內屢次 postValue
,LiveData
只會保留最後一個來通知觀察者)。app
固然,這只是LiveData
用法的簡單說明,實際項目中若是這樣用會有些問題:
LiveData
來解決這個問題Activity
或 Fragment
會重建致使數據丟失,這個問題固然能夠經過 onSaveInstanceState
來保留和恢復數據;LiveData
,單例能夠解決這個問題,但數據源不在被須要時也沒法回收資源。上面說的這些問題均可以經過某些手段解決,可是都不是很優雅,而谷歌固然考慮到了,這些問題在接下來的 ViewModel
中,都獲得了很好的解決。
ViewModel
,顧名思義,是用來存儲和管理 View 相關數據的,而 AAC 中的 ViewModel
還能夠感知生命週期,能夠在配置變動(如屏幕旋轉)時自動保存數據,還能夠在生命週期真的結束時觸發回調來清除沒必要要的請求,以避免內存泄漏。而做爲 MVVM 的中間層,它還肩負着響應 View 層的動做,以及操做 Model 層請求數據的任務。ViewModel
的生命週期以下圖所示:
ViewModel
因爲生命週期是長於 View 層(
Activity
,
Fragment
或
View
)的,不能(也不須要)持有 View 層的任何東西,若是要使用 context 能夠繼承
AndroidViewModel
,它內部持有 Application 的 context。
public class MyViewModel extends ViewModel {
// ...
public List<User> getUsers() {
return users;
}
public void loadUsers() {
// 請求 users 數據.
}
// 一、調用時機
@Override
protected void onCleared() {
// 清除沒必要要的請求
}
}
public class MyActivity extends AppCompatActivity {
public void onCreate(Bundle savedInstanceState) {
// MyActivity 重建時仍是能拿到同一個 MyViewModel
// 二、ViewModelProviders.of 參數
MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
model.loadUsers();
}
}
複製代碼
一、ViewModel
的 onCleared
函數會在持有它的對象的生命週期結束時調用,以避免異步請求形成 ViewModel
的內存泄露;
二、public static ViewModelProvider of(@NonNull FragmentActivity activity)
或 public static ViewModelProvider of(@NonNull Fragment fragment)
,傳入的參數能夠是 Activity
或 Fragment
,其內部會拿到 Activity
或 Fragment
的 ViewModelStore
,顧名思義就是存儲 ViewModel
的地方,其內部也只是一個 HashMap<String, ViewModel>
,鍵是內部用 ViewModel
的 Class
的名字拼出的字符串。
利用 ViewModelStore
存儲 ViewModel
能夠十分方便地管理 ViewModel
,前面說的 ViewModel
能夠在配置變動後存活,其實就是在重建保存狀態時,保存下了 ViewModelStore
,實現方式和保存 Fragment
相似(Bundle
保存的數據是有限的,爲了在配置變動時保存大量數據,也能夠用 Fragment
來存)。利用 ViewModelStore
存儲 ViewModel
的方式還能夠方便 Fragment
之間的通信和數據同步,只要多個 Fragment
隸屬於 同一個 Activity
,他們就能夠經過 Activity
的 ViewModelStore
拿到同一個 ViewModel
。
雖然 LiveData
和 ViewModel
單獨拿出來用也是強有力的工具,谷歌推出 AAC 的目的明顯不只僅是一個工具,這一整套服務於的架構相關的組件能夠幫助咱們輕鬆的打造 MVVM,並且都帶着生命週期感知能力。接下來經過一個計數器例子,簡單介紹下使用方法。
public class CountViewModel extends ViewModel {
private final MutableLiveData<Integer> mCountLiveData = new MutableLiveData<Integer>();
public LiveData<Integer> getCountLiveData() { return mCountLiveData; }
public void loadCount() {
// 能夠經過網絡或數據庫請求數據
request.enquen(response -> {
if (response.isSuccess()) {
mCountLiveData.postValue(response.data);
}
});
}
public void countDown() {
// 減少計數
if (mCountLiveData.getValue() != null) {
mCountLiveData.setValue(mCountLiveData.getValue() - 1);
} else {
loadCount();
}
}
public void countUp() {
// 增大計數
if (mCountLiveData.getValue() != null) {
mCountLiveData.setValue(mCountLiveData.getValue() + 1);
} else {
loadCount();
}
}
}
public class ActionFragment extends Fragment {
//...
@Override
public void onViewCreated(View v, Bundle savedInstanceState) {
final CountViewModel countViewModel = ViewModelProviders.of(getActivity()).get(MyViewModel.class);
// 改變計數值
v.findViewById(R.id.up_buttonn).setOnClickListener(v -> {
countViewModel.countUp();
});
v.findViewById(R.id.down_buttonn).setOnClickListener(v -> {
countViewModel.countDown();
});
}
//...
}
public class ShowCountFragment extends Fragment {
//...
@Override
public void onViewCreated(View v, Bundle savedInstanceState) {
final TextView count = v.findViewById(R.id.count_text_view);
// 這裏的 getActivity() 是爲了拿到同一個 CountViewModel
ViewModelProviders.of(getActivity())
.get(CountViewModel.class)
.getCountLiveData()
// 這裏的 this 是爲了讓 LiveData 綁定觀察者的生命週期
.observe(this, data -> {
count.setText(data);
});
}
//...
}
複製代碼
在該例子中,CountViewModel
中有一個 mCountLiveData
用於保存計數值,還有一組用於更新計數值的方法;ActionFragment
和 ShowCountFragment
位於同一個 Activity
中,這樣能夠保證二者拿到同一個 CountViewModel
,ActionFragment
的兩個按鈕用於增減計數,而 ShowCountFragment
則監聽並顯示計數值。
這樣一個簡單的 MVVM 架構的計數器就搭建好了。View 層的 ShowCountFragment
綁定 ViewModel 層的 mCountLiveData
,並在數據變動時更新視圖,而 ViewModel 層不須要直接持有任何 View 層的引用(LiveData
持有的觀察者在 View 層,可是會自動根據生命週期來移除),ViewModel 也不關心監聽數據的 View 的數量和類型,View 拿到數據後顯示什麼東西也都無所謂,多一個 View 只不過是多了一個觀察者而已,並且多個 View 不須要藉助其餘工具(EventBus、RxBus 等事件總線)就能夠經過 ViewModel 實現通訊。
對於數據源比較多的場景,谷歌建議咱們單獨抽出 Repository 層(其實就是 Model 層)用於處理數據來源(緩存、數據庫或網絡),並向上返回數據的 LiveData
(如 Room)來保持數據的同步,整個架構圖以下圖所示:
**配合源碼使用,效果更佳!**特別推薦使用 androidx 來看源碼,會清晰方便不少。
View 層的動態性很強,各個界面切換、視圖元素交替出現等都伴隨着生命週期的變化,而下層元素的生命週期每每要長於 View 的生命週期,爲了避免形成資源浪費和內存泄漏,咱們時常須要手動管理 View 的生命週期。好比咱們有一個顯示當前位置的 Activity
,咱們須要在 onStart
時開始監聽位置信息,並在位置變化時更改視圖,在 onStop
時註銷監聽。
Activity
和
Fragment
的生命週期是一件十分繁瑣並且低效的事情,爲了更有效地管理生命週期,許多第三方庫(例如 Glide、RxLifecycle)都將監聽與分發生命週期地任務交給
Frgament
,由於只要將
Frgament
塞進
Activity
中,
Frgament
就能與
Activity
生命週期同步,而後經過自定義的
Frgament
將生命週期事件發送出來。AAC 中的 Lifecycle 組件也是經過這種方式和觀察者模式實現了生命週期地自動管理。
Lifecycle 組件主要有 Lifecycle
、LifecycleObserver
和一套相關地類組成。Lifecycle
定義了一系列生命週期地狀態和事件,其惟一子類 LifecycleRegistry
則實現了一個做爲生命週期被觀察者所具備的能力,在生命週期變化時向觀察者們分發事件。LifecycleObserver
是一個起標識做用地接口,它的子接口 LifecycleEventObserver
的 onStateChanged
方法在 LifecycleRegistry
分發生命週期時會被回調。
如今問題來了:
Lifecycle
Lifecycle
的持有者都會實現 LifecycleOwner
接口,重寫 Lifecycle getLifecycle();
方法,返回本身持有的生命週期對象 LifecycleRegistry
,Activity
和 Fragment
都實現了該接口。
Lifecycle
的生命週期事件從哪裏來,和以前說的 Frgament
有什麼關係?LifecycleOwner
的實現類既然持有 Lifecycle
,那確定就會發送事件啦。Frgament
的話比較簡單,內部保存了一個 mLifecycleRegistry
,並在本身的生命週期事件中調用 mLifecycleRegistry
的 handleLifecycleEvent
方法將事件傳遞給 LifecycleRegistry
。Activity
本身也持有一個 mLifecycleRegistry
,可是它不本身發送事件,而是把任務交給了一個叫 ReportFragment
的 Fragment
,其實現也很簡單,就是在本身的生命週期事件中拿到 Activity
的 mLifecycleRegistry
,而後再進行分發。
LifecycleObserver
怎麼用須要監聽 Lifecycle
的對象實現這個接口,而後在 onStateChanged
方法中根據不一樣的生命週期作出相應的動做。好比前面說的監聽位置信息的例子,咱們就能夠單獨抽出一個對象來專門作監聽操做,實現 LifecycleObserver
接口,並本身處理生命週期事件。
class MyLocationListener implements LifecycleObserver {
private boolean enabled = false;
public MyLocationListener(Context context, Lifecycle lifecycle, Callback callback) {
//...
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
void start() {
if (enabled) {
// connect
}
}
public void enable() {
enabled = true;
if (lifecycle.getCurrentState().isAtLeast(STARTED)) {
// connect if not connected
}
}
@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
void stop() {
// disconnect if connected
}
}
複製代碼
這裏咱們來扒一扒源碼,看 ViewModel
是如何建立、如何挺過配置變動,又是什麼時候真正的消失的。
ViewModel
的建立前面咱們已經知道 ViewModel
都保存在 ViewModelStore
中,那隻要知道 ViewModelStore
如何被建立、保存與銷燬就行。在 ComponentActivity
的 getViewModelStore
方法能夠看到 ViewModelStore
的建立過程。
if (mViewModelStore == null) {
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
// Restore the ViewModelStore from NonConfigurationInstances
mViewModelStore = nc.viewModelStore;
}
if (mViewModelStore == null) {
mViewModelStore = new ViewModelStore();
}
}
複製代碼
能夠看到 ViewModelStore
是從一個叫 NonConfigurationInstances
的實例中拿的,若是拿不到說明以前沒經歷過配置變動,那就 new 一個出來。接着看
// ComponentActivity 裏的
static final class NonConfigurationInstances {
Object custom;
ViewModelStore viewModelStore;
}
複製代碼
NonConfigurationInstances
除了保存 ViewModelStore
還存着 custom
用於保存咱們本身定製的數據,這個能夠經過重寫 onRetainCustomNonConfigurationInstance
方法來用。再來看下 getLastNonConfigurationInstance
public Object getLastNonConfigurationInstance() {
return mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.activity : null;
}
// 這個是 Activity 中的,和 ComponentActivity 裏的那個不同
static final class NonConfigurationInstances {
Object activity;
HashMap<String, Object> children;
FragmentManagerNonConfig fragments;
ArrayMap<String, LoaderManager> loaders;
VoiceInteractor voiceInteractor;
}
複製代碼
是在 Activity
的 NonConfigurationInstances
中的 activity
,經過 NonConfigurationInstances
咱們也能大體看出 Fragment
在配置變動的時候會被保存到 FragmentManagerNonConfig
中。
在 ComponentActivity
的 onRetainNonConfigurationInstance
中會分別拿咱們定製的 custom
和 ViewModelStore
,而後返回建立好的 NonConfigurationInstances
。而 onRetainNonConfigurationInstance
會在配置變動時被 LocalActivityManager
的 dispatchRetainNonConfigurationInstance
方法中調用,從而保存狀態信息。至此咱們就知道保存 ViewModelStore
的流程,再繼續深刻源碼就沒法自拔了。
ViewModel
,調用它的 onCleared
getLifecycle().addObserver(new GenericLifecycleObserver() {
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
if (!isChangingConfigurations()) {
getViewModelStore().clear();
}
}
}
});
複製代碼
在 ComponentActivity
的構造函數中有這麼一段代碼,恰好用到了咱們前面說的 Lifecycle
和 LifecycleObserver
,在 ON_DESTROY 時判斷下是不是配置變動,不是的話就調用 ViewModelStore
的 clear
方法,會清除 ViewModelStore
中保存的 ViewModel
,並調用他們的 clear
方法,進而調用到 onCleared
。
至此,Activiy
中的 ViewModel
相關生命週期已經分析完了,Fragment
中也大同小異,主要涉及 FragmentManagerImpl
、FragmentManagerViewModel
等一些類,感興趣的能夠順着 ViewModelStore
的思路,本身深刻了解下。
觀察者模式的那套東西均可以玩一些騷操做,責任鏈、事件總線什麼的,LiveData
做爲一個可觀察對象,固然也能夠,這裏簡單分析兩個。
首先了解下一個叫 MediatorLiveData
的對象,它繼承自 MutableLiveData
,經過 public <S> void addSource(@NonNull LiveData<S> source, @NonNull Observer<? super S> onChanged)
方法實現了增長其餘 LiveData
做爲本身事件源的功能,源 LiveData
更新時,會調用傳入的 Observer
的 onChanged
方法作處理。MediatorLiveData
是利用 public void observeForever(@NonNull Observer<? super T> observer)
方法來添加源的,這個方法不須要傳 LifecycleOwner
,可是須要手動移除觀察者,不過不用擔憂,MediatorLiveData
已經幫咱們作了。若是 MediatorLiveData
已經沒有任何觀察者,它會自動調用源 LiveData
的 removeObserver
方法來移除對源 LiveData
的監聽,以防本身內存泄漏。
利用 MediatorLiveData
對象,咱們能夠作一些事件變換的操做,Transformations
的 map
和 switchMap
就是經過該對象實現的。
以前的事件總線都須要手動處理生命週期的問題,EventBus 須要手動註銷,RxBus 須要 RxLifecycle
的擴展庫來監聽生命週期。有了 LiveData,咱們徹底能夠用不多的代碼擼一個具備生命週期感知能力的事件總線,實現很簡單(一個簡單但實用的 LiveDataBus 只須要一百行代碼左右),網上也有不少開源的庫,這裏只講下大體思路。
要想作事件總線,核心就是發送方和接收方拿到同一個可觀察對象,在這裏就是同一個 LiveData
。最簡單的方法就是定義一個單例類,假設叫 LiveDataBus
,裏面放一個 Map<Class<?>, MutableLiveData<?>>
來保存全部的事件類型 Class
和對應的 LiveData
,這樣就能經過事件的 Class
拿到對應的惟一 LiveData
。這裏有幾個須要注意的地方:
Map
的併發問題,由於來拿 LiveData
的可能多個線程的,因此要作好同步工做,再考慮到可見性,建議用 ConcurrentHashMap
;Map
裏存的 Class
和 MutableLiveData
都被擦出了泛型(不一樣事件的 Class<T>
裏泛型確定不同呀),因此要本身保證二者的泛型一致,能夠定義一個保存 Class<T>
和 MutableLiveData<T>
的帶泛型 <T>
的類,在裏面保證一致;LiveDataBus
中的 LiveData
不會被釋放,也就致使它裏面的數據不會被釋放,能夠在事件不用時發送一個空事件;注意:ViewModel
已經可以解決不少場合的通訊問題,並且能在不用時釋放掉,因此能用 ViewModel
通訊的就不要用事件總線,除非兩個 Activity
必須經過某種方式進行通信,也要先考慮下單例的 LiveData
,實在不行再用事件總線。
最後再強調一遍,不要濫用事件總線
LiveData
源碼很少,這裏只簡單分析幾個 LiveData
的特性。
從 LiveData
的訂閱方法看起
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// ...
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
// ...
owner.getLifecycle().addObserver(wrapper);
}
複製代碼
能夠看到 LiveData
不只是一個可觀察對象,同時仍是一位觀察者,它所觀察的就是 Activity
或 Fragment
等持有 Lifecycle
的 LifecycleOwner
,固然也要把觀察本身的觀察者保存下來,接下來看下 LifecycleBoundObserver
這個觀察者是怎麼處理 Lifecycle
的。首先它繼承自 ObserverWrapper
這是一個會根據 Lifecycle
是否處於激活狀態決定是否分發數據的觀察者,這裏先跳過,LifecycleBoundObserver
還實現了 GenericLifecycleObserver
接口,其實就是前面說過的 LifecycleEventObserver
,它的生命週期狀態回調函數以下:
// LifecycleBoundObserver 的方法
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
// LiveData 的方法
public void removeObserver(@NonNull final Observer<? super T> observer) {
// ...
ObserverWrapper removed = mObservers.remove(observer);
// ...
removed.detachObserver();
removed.activeStateChanged(false);
}
// LifecycleBoundObserver 的方法
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
複製代碼
onStateChanged
在判斷 Lifecycle
DESTROYED 的時候調用 LiveData
的 removeObserver
,首先將觀察 LiveData
的觀察者移除,防止內存泄漏,以後再調用LifecycleBoundObserver
的 detachObserver
將本身從 LifecycleOwner
的觀察者中移除,自此將相互之間的觀察狀態接觸。
作預加載的時候,咱們能夠在 Activity
或 Fragment
建立時直接請求數據,塞到 LiveData
,而後只要生命週期處於激活狀態,無論何時監聽 LiveData
,都能收到最新的消息。咱們再來看一下 LifecycleBoundObserver
的 onStateChanged
方法,它在最後調用了父類的 activeStateChanged(shouldBeActive())
方法,來大體看一下
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
// 該方法是 LiveData 的
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
// 該方法是 LiveData 的
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
複製代碼
它首先會根據當前的激活狀態進行去重,而後會根據 LiveData
的觀察者處於激活狀態的數量和新的狀態判斷是否調用 onActive
和 onInactive
,這兩個也是 LiveData
的重要回調,不過都好理解,就不在細說了。最後會判斷如今是不是激活狀態,是的話就調用 LiveData
的 dispatchingValue
方法,顧名思義就是 LiveData
向其觀察者發送通知。而 dispatchingValue
接收一個 ObserverWrapper
的參數,若是不爲空就是說只用通知這個特定的觀察者,不然通知全部處於激活的觀察者。
setValue
和 postValue
setValue
直接改變當前的值,而後調用 dispatchingValue(null)
來通知全部激活狀態的觀察者,不過必須在主線程調用不然會拋異常。由於其餘線程也均可以直接改變當前值的話會形成併發,加鎖的話又會影響性能。
因此就又搞了一個 postValue
,它首先在拿到同步鎖的狀況下把值存到 mPendingData
,而後向主線程的 Handler
拋一個更新當前值的 mPostValueRunnable
,這個 mPostValueRunnable
在執行時也是先拿同步鎖,而後調用 setValue
(如今在主線程)把 mPendingData
設置到當前值。在 mPostValueRunnable
拋出去以後且還未執行前,若是再次調用 postValue
就又會修改 mPendingData
的值,而不會再次向 Handler
拋一次 mPostValueRunnable
,這樣就致使了後設置的值覆蓋掉前面設置的,最後只會向觀察者們通知最新的值。這個是須要注意的點,谷歌可能認爲既然只是在主線程更新 View,那你拿最新的值就行,其餘的都無所謂,固然這樣也起到流量控制的做用,防止短期內過多的事件觸發無用的回調。
谷歌推出的 AAC 庫很好的解決了平常使用中的生命週期問題,使咱們能夠專心於業務層面的設計,而不須要再爲生命週期等問題擔心。LiveData
和 ViewModel
確實好用,但用的時候也有須要注意的地方,ViewModel 層實際應用中要上承 View 層,提供必要的動做和數據,下接 Model 層,作好數據處理,都有不少須要考慮的地方,以後有時間再談談我在使用 AAC 的路上的經驗和總結。
博客的 Github 倉庫 歡迎你們 Start & Fork !