Android Jetpack框架之LiveData與ViewModel

Android Jetpack框架之LiveData與ViewModel分析與使用

1魁索、前言

Google 為了幫助 Android 開(kāi)發(fā)者更快更好地開(kāi)發(fā) App,推出了一系列組件,這些組件被打包成了一個(gè)整體,稱作 Android Jetpack躯砰,它包含的組件如下圖所示

框架圖

jetpack概覽

官方對(duì)應(yīng) Architecture 的說(shuō)明:

Android architecture components are a collection of libraries that help you design robust, testable, and maintainable apps. Start with classes for managing your UI component lifecycle and handling data persistence.
Manage your app's lifecycle with ease. New lifecycle-aware components help you manage your activity and fragment lifecycles. Survive configuration changes, avoid memory leaks and easily load data into your UI.
Use LiveData to build data objects that notify views when the underlying database changes.
ViewModel Stores UI-related data that isn't destroyed on app rotations.
Room is an a SQLite object mapping library. Use it to Avoid boilerplate code and easily convert SQLite table data to Java objects. Room provides compile time checks of SQLite statements and can return RxJava, Flowable and LiveData observables.

翻譯:

Android體系結(jié)構(gòu)組件是一組庫(kù),可幫助您設(shè)計(jì)健壯携丁,可測(cè)試和可維護(hù)的應(yīng)用程序琢歇。 從用于管理UI組件生命周期和處理數(shù)據(jù)持久性的類開(kāi)始。
輕松管理應(yīng)用程序的生命周期梦鉴。 新的生命周期感知組件可幫助您管理活動(dòng)和碎片生命周期李茫。 生存配置更改,避免內(nèi)存泄漏并輕松將數(shù)據(jù)加載到UI中肥橙。
使用LiveData構(gòu)建數(shù)據(jù)對(duì)象魄宏,以便在基礎(chǔ)數(shù)據(jù)庫(kù)更改時(shí)通知視圖。
ViewModel存儲(chǔ)在應(yīng)用程序輪換中未銷毀的UI相關(guān)數(shù)據(jù)存筏。
Room是一個(gè)SQLite對(duì)象映射庫(kù)宠互。 使用它來(lái)避免樣板代碼并輕松地將SQLite表數(shù)據(jù)轉(zhuǎn)換為Java對(duì)象。 Room提供SQLite語(yǔ)句的編譯時(shí)檢查椭坚,可以返回RxJava予跌,F(xiàn)lowable和LiveData observable。

官方推薦的應(yīng)用架構(gòu)指南

常見(jiàn)架構(gòu)原則
1.分離關(guān)注點(diǎn)
要遵循的最重要的原則是分離關(guān)注點(diǎn)一種常見(jiàn)的錯(cuò)誤是在一個(gè) ActivityFragment中編寫所有代碼善茎。這些基于界面的類應(yīng)僅包含處理界面和操作系統(tǒng)交互的邏輯券册。應(yīng)盡可能使這些類保持精簡(jiǎn),這樣可以避免許多與生命周期相關(guān)的問(wèn)題。

請(qǐng)注意烁焙,您并不擁有 ActivityFragment的實(shí)現(xiàn)航邢,這些只是表示 Android 操作系統(tǒng)與應(yīng)用之間關(guān)系的粘合類。操作系統(tǒng)可能會(huì)根據(jù)用戶交互或因內(nèi)存不足等系統(tǒng)條件隨時(shí)銷毀它們骄蝇。為了提供令人滿意的用戶體驗(yàn)和更易于管理的應(yīng)用維護(hù)體驗(yàn)膳殷,最好盡量減少對(duì)它們的依賴。
2.用過(guò)模型驅(qū)動(dòng)界面
另一個(gè)重要原則是您應(yīng)該通過(guò)模型驅(qū)動(dòng)界面乞榨,最好是持久性模型秽之。模型是負(fù)責(zé)處理應(yīng)用數(shù)據(jù)的組件当娱。它們獨(dú)立于應(yīng)用中的 View 對(duì)象和應(yīng)用組件吃既,因此不受應(yīng)用的生命周期以及相關(guān)關(guān)注點(diǎn)的影響。
持久性是理想之選跨细,原因如下

  • 如果 Android 操作系統(tǒng)銷毀應(yīng)用以釋放資源鹦倚,用戶不會(huì)丟失數(shù)據(jù)。
  • 當(dāng)網(wǎng)絡(luò)連接不穩(wěn)定或不可用時(shí)冀惭,應(yīng)用會(huì)繼續(xù)工作震叙。

應(yīng)用所基于的模型類應(yīng)明確定義數(shù)據(jù)管理職責(zé),這樣將使應(yīng)用更可測(cè)試且更一致散休。

看下圖媒楼,該圖顯示了設(shè)計(jì)應(yīng)用后所有模塊應(yīng)如何交互


架構(gòu)指南圖

請(qǐng)注意,每個(gè)組件僅依賴于其下一級(jí)的組件戚丸。例如划址,Activity 和 Fragment 僅依賴于視圖模型。存儲(chǔ)區(qū)是唯一一個(gè)依賴于其他多個(gè)類的類限府;在本例中夺颤,存儲(chǔ)區(qū)依賴于持久性數(shù)據(jù)模型和遠(yuǎn)程后端數(shù)據(jù)源。

這種設(shè)計(jì)打造了一致且愉快的用戶體驗(yàn)胁勺。無(wú)論用戶是在上次關(guān)閉應(yīng)用幾分鐘后還是幾天后回到應(yīng)用世澜,他們都會(huì)立即看到應(yīng)用在本地保留的用戶信息。如果此數(shù)據(jù)已過(guò)時(shí)署穗,則應(yīng)用的存儲(chǔ)區(qū)模塊將開(kāi)始在后臺(tái)更新數(shù)據(jù)寥裂。

2、介紹LiveData與ViewModel

ViewModel類旨在以生命周期意識(shí)的方式存儲(chǔ)和管理與UI相關(guān)的數(shù)據(jù)。 ViewModel類允許數(shù)據(jù)在配置更改(例如屏幕旋轉(zhuǎn))后繼續(xù)存在臀玄。
示例代碼

public class FlowerModel extends ViewModel {
    private MutableLiveData<Data> liveData;
    public MutableLiveData<Data> getLiveData() {
        if (liveData == null){
            liveData = new MutableLiveData<>();
        }
        return liveData;
    }
    public static class Data {
        public int send;
        public int less;
        public List<PaintView.DrawPath> list;
    }
}
flowerModel = ViewModelProviders.of(getActivity()).get(FlowerModel.class);

然后利用LiveData通知界面更新UI
LiveData 是一種可觀察的數(shù)據(jù)存儲(chǔ)器拄衰。應(yīng)用中的其他組件可以使用此存儲(chǔ)器來(lái)監(jiān)控對(duì)象的更改,而無(wú)需在它們之間創(chuàng)建明確且嚴(yán)格的依賴路徑俭驮。LiveData 組件還遵循應(yīng)用組件(如 Activity、Fragment 和 Service)的生命周期狀態(tài),并包括清理邏輯以防止對(duì)象泄漏和過(guò)多的內(nèi)存消耗混萝。

  flowerModel.getLiveData().observe(getActivity(), new Observer<FlowerModel.Data>() {
            @Override
            public void onChanged(@Nullable FlowerModel.Data data) {
                //update UI
            }
        });

Demo演示

3遗遵、項(xiàng)目中應(yīng)用

4、淺析原理與使用

ViewModel生命周期

  • ViewModel對(duì)象的范圍是在獲取ViewModel時(shí)傳遞給ViewModelProvider的Lifecycle生命周期-
  • ViewModel在內(nèi)存中直到Activity銷毀或Fragment被移除
  • 系統(tǒng)首次調(diào)用活動(dòng)對(duì)象的onCreate()方法時(shí)逸嘀,通常會(huì)請(qǐng)求ViewModel
  • 系統(tǒng)可能會(huì)在整個(gè)活動(dòng)的整個(gè)生命周期中多次調(diào)用onCreate()车要,例如當(dāng)設(shè)備屏幕旋轉(zhuǎn)時(shí)
  • ViewModel從第一次請(qǐng)求ViewModel直到活動(dòng)完成并銷毀時(shí)存在
    ViewModel生命周期圖

    看源碼
    1,獲取ViewModelProvider
    ViewModelProviders提供四個(gè)構(gòu)造方法創(chuàng)建VIewProvider,兩個(gè)帶有factory兩個(gè)沒(méi)有崭倘,不過(guò)沒(méi)有factory的其實(shí)使用的是默認(rèn)的Factory翼岁,所以四個(gè)方法基本一致只是Fragment和Activity的區(qū)分
@NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull Fragment fragment) {
        return of(fragment, null);
    }

    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull FragmentActivity activity) {
        return of(activity, null);
    }
    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull Fragment fragment, @Nullable Factory factory) {
        Application application = checkApplication(checkActivity(fragment));
        if (factory == null) {
            factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
        }
        return new ViewModelProvider(ViewModelStores.of(fragment), factory);
    }

    @NonNull
    @MainThread
    public static ViewModelProvider of(@NonNull FragmentActivity activity,
            @Nullable Factory factory) {
        Application application = checkApplication(activity);
        if (factory == null) {
            factory = ViewModelProvider.AndroidViewModelFactory.getInstance(application);
        }
        return new ViewModelProvider(ViewModelStores.of(activity), factory);
    }

獲取ViewModelStore:由前面的源碼可以知道創(chuàng)建ViewProvider時(shí)傳入兩個(gè)參數(shù):ViewModelStore 和 Factory;顯然從名字就可以看出他們的作用司光,F(xiàn)actory負(fù)責(zé)創(chuàng)建琅坡,ViewModelStore負(fù)責(zé)存儲(chǔ)

@NonNull
    @MainThread
    public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
        ViewModel viewModel = mViewModelStore.get(key);

        if (modelClass.isInstance(viewModel)) {
            //noinspection unchecked
            return (T) viewModel;
        } else {
            //noinspection StatementWithEmptyBody
            if (viewModel != null) {
                // TODO: log a warning.
            }
        }

        viewModel = mFactory.create(modelClass);
        mViewModelStore.put(key, viewModel);
        //noinspection unchecked
        return (T) viewModel;
    }

上面的執(zhí)行是,先去ViewModelStore中獲取残家,如果為空就調(diào)用Factory的create()創(chuàng)建ViewModel榆俺,并儲(chǔ)存在VIewmoStore中

ViewModelProviders.of(SquareFragment.this).get(AudioLiveData.class)的執(zhí)行流程大概圖 忽略創(chuàng)建和存儲(chǔ)細(xì)節(jié)

viewModel創(chuàng)建1

2,通過(guò)ViewModelStores.of(this)創(chuàng)建ViewModelStore 源碼

    private ViewModelStores() {
    }
    @NonNull
    @MainThread
    public static ViewModelStore of(@NonNull FragmentActivity activity) {
        if (activity instanceof ViewModelStoreOwner) {
            return ((ViewModelStoreOwner) activity).getViewModelStore();
        }
        return holderFragmentFor(activity).getViewModelStore();
    }
    @NonNull
    @MainThread
    public static ViewModelStore of(@NonNull Fragment fragment) {
        if (fragment instanceof ViewModelStoreOwner) {
            return ((ViewModelStoreOwner) fragment).getViewModelStore();
        }
        return holderFragmentFor(fragment).getViewModelStore();
    }

先判斷Activity是否為 ViewModelStoreOwner坞淮,如果是直接獲取其中的ViewModelStore茴晋,否則調(diào)用holderFragmentFor(activity).getViewModelStore()獲取

    @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
    public static HolderFragment holderFragmentFor(FragmentActivity activity) {
        return sHolderFragmentManager.holderFragmentFor(activity);
    }
...
    HolderFragment holderFragmentFor(FragmentActivity activity) {
            FragmentManager fm = activity.getSupportFragmentManager();
            //通過(guò)manager.findFragmentByTag(HOLDER_TAG)找到fragment
            HolderFragment holder = findHolderFragment(fm);
            if (holder != null) {
                return holder;
            }
            holder = mNotCommittedActivityHolders.get(activity);
            //在map中取
            if (holder != null) {
                return holder;
            }

            if (!mActivityCallbacksIsAdded) {
                mActivityCallbacksIsAdded = true;
                activity.getApplication().registerActivityLifecycleCallbacks(mActivityCallbacks);
            }
            //創(chuàng)建 HolderFragment
            holder = createHolderFragment(fm);
            //存到map中
            mNotCommittedActivityHolders.put(activity, holder);
            return holder;
        }

其中 findHolderFragment

private static HolderFragment findHolderFragment(FragmentManager manager) {
            if (manager.isDestroyed()) {
                throw new IllegalStateException("Can't access ViewModels from onDestroy");
            }

            Fragment fragmentByTag = manager.findFragmentByTag(HOLDER_TAG);
            if (fragmentByTag != null && !(fragmentByTag instanceof HolderFragment)) {
                throw new IllegalStateException("Unexpected "
                        + "fragment instance was returned by HOLDER_TAG");
            }
            return (HolderFragment) fragmentByTag;
        }

map中g(shù)et

@SuppressWarnings("WeakerAccess")
    static class HolderFragmentManager {
        private Map<Activity, HolderFragment> mNotCommittedActivityHolders = new HashMap<>();
        private Map<Fragment, HolderFragment> mNotCommittedFragmentHolders = new HashMap<>();
...
    holder = mNotCommittedActivityHolders.get(activity);

createHolderFragment

private static HolderFragment createHolderFragment(FragmentManager fragmentManager) {
            HolderFragment holder = new HolderFragment();
            fragmentManager.beginTransaction().add(holder, HOLDER_TAG).commitAllowingStateLoss();
            return holder;
        }

3, HolderFragment存儲(chǔ)ViewModelStore
上面都是獲取或者創(chuàng)建HolderFragment的過(guò)程,有沒(méi)有想過(guò)我們存儲(chǔ)ViewModel的地方回窘,為什么一直在操作fragment 诺擅?我們回頭看創(chuàng)建ViewModelStore的地方
有這么個(gè)判斷 activity instanceof ViewModelStoreOwner

@NonNull
    @MainThread
    public static ViewModelStore of(@NonNull FragmentActivity activity) {
        if (activity instanceof ViewModelStoreOwner) {
            return ((ViewModelStoreOwner) activity).getViewModelStore();
        }
        return holderFragmentFor(activity).getViewModelStore();
    }
...
public interface ViewModelStoreOwner {

    @NonNull
    ViewModelStore getViewModelStore();
}

而HolderFragment實(shí)現(xiàn)了ViewModelStoreOwner,同時(shí)保存了ViewModelStore

@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class HolderFragment extends Fragment implements ViewModelStoreOwner {
...
private ViewModelStore mViewModelStore = new ViewModelStore();
@NonNull
    @Override
    public ViewModelStore getViewModelStore() {
        return mViewModelStore;
    }

ViwModelStore 利用HashMap獲取,存儲(chǔ) ViewModel

public class ViewModelStore {
    private final HashMap<String, ViewModel> mMap = new HashMap<>();
    final void put(String key, ViewModel viewModel) {
        ViewModel oldViewModel = mMap.put(key, viewModel);
        if (oldViewModel != null) {
            oldViewModel.onCleared();
        }
    }
    final ViewModel get(String key) {
        return mMap.get(key);
    }
    public final void clear() {
        for (ViewModel vm : mMap.values()) {
            vm.onCleared();
        }
        mMap.clear();
    }
}

獲取ViewModelStore的整體執(zhí)行流程


ViewModelStore創(chuàng)建2

總結(jié)一下ViewModel內(nèi)部的存儲(chǔ)邏輯

  • 根據(jù)傳入的Activity/Fragment獲取啡直、創(chuàng)建烁涌、添加并以activity為鍵保存Fragment(因此在屏幕發(fā)生旋轉(zhuǎn)時(shí)生命周期改變兩次創(chuàng)建activity時(shí)獲取的都是同一個(gè)fragment因?yàn)閗ey相同)
  • 獲取Fragment中保存的ViewModelStore對(duì)象(ViewModelStore中使用Map儲(chǔ)存ViewModel)
  • 創(chuàng)建ViewModelProvider實(shí)例,ViewModelProvider中封裝了獲取的ViewModelStore和創(chuàng)建用的Factory
  • 從VIewModelStore的Map中或Factory的create()中獲取ViewModel

LiveData 是一個(gè)觀察者模型付枫,但是它是一個(gè)與 Lifecycle 綁定了的 Subject烹玉,也就是說(shuō),只有當(dāng) UI 組件處于 ACTIVE 狀態(tài)時(shí)阐滩,它的 Observer 才能收到消息二打,否則會(huì)自動(dòng)切斷訂閱關(guān)系

  • LiveData 只要有數(shù)據(jù)更新,它的 observer 就會(huì)收到通知掂榔。如果我們要把 LiveData 用作事件總線(類似EventBus)继效,還需要做一些定制,可以使用google官方demo里的 SingleLiveEvent 装获。
public class SingleLiveEvent<T> extends MutableLiveData<T> {
    private static final String TAG = "SingleLiveEvent";
    private final AtomicBoolean mPending = new AtomicBoolean(false);
    @MainThread
    public void observe(LifecycleOwner owner, final Observer<T> observer) {
        if (hasActiveObservers()) {
            Log.w(TAG, "Multiple observers registered but only one will be notified of changes.");
        }
        // Observe the internal MutableLiveData
        super.observe(owner, new Observer<T>() {
            @Override
            public void onChanged(@Nullable T t) {
                if (mPending.compareAndSet(true, false)) {
                    observer.onChanged(t);
                }
            }
        });
    }
    @MainThread
    public void setValue(@Nullable T t) {
        mPending.set(true);
        super.setValue(t);
    }
    /**
     * Used for cases where T is Void, to make calls cleaner.
     */
    @MainThread
    public void call() {
        setValue(null);
    }
}
  • 我們沒(méi)法直接修改 LiveData 的 value瑞信,因?yàn)樗遣豢勺兊模╥mmutable),可變(mutable)版本是 MutableLiveData穴豫,通過(guò)調(diào)用 setValue(主線程)或 postValue(非主線程)可以修改它的 value
  • LiveData 有一個(gè)實(shí)現(xiàn)了中介者模式的子類 —— MediatorLiveData凡简,它可以把多個(gè) LiveData 整合成一個(gè)逼友,只要任何一個(gè) LiveData 有數(shù)據(jù)變化,它的觀察者就會(huì)收到消息

匯總一下 LiveData 的使用場(chǎng)景:

* LiveData - immutable 版本*
* MutableLiveData - mutable 版本
* MediatorLiveData - 可匯總多個(gè)數(shù)據(jù)源
* SingleLiveEvent - 事件總線

LiveData轉(zhuǎn)換

  • Transformations.map 對(duì)存儲(chǔ)在LiveData對(duì)象中的值修改秤涩,并將結(jié)果發(fā)送到下游
 private class User{
        private User(String id){ this.userId = id; }
        private String userName;
        private String userId;
    }
    private MutableLiveData<User> userMutableLiveData;
    public void test(){
        userMutableLiveData = new MutableLiveData<>();
        LiveData<String> userName = Transformations.map(userMutableLiveData, new Function<User, String>() {
            @Override
            public String apply(User input) {

                return "姓名"+input.userName;
            }
        });
  • Transformations.switchMap 動(dòng)態(tài)返回LiveData
private class User{
        private User(String id){ this.userId = id; }
        private String userName;
        private String userId;
    }
    private MutableLiveData<User> userMutableLiveData;
    public void test(){
        userMutableLiveData = new MutableLiveData<>();
        LiveData<String> userId = new MutableLiveData<>();
        LiveData<User> user2 = Transformations.switchMap(userId, new Function<String, LiveData<User>>() {
            @Override
            public LiveData<User> apply(String input) {
                return getUser(input);
            }
        });
    }
    private LiveData<User> getUser(String id){
        User user = new User(id);
         userMutableLiveData.setValue(user);
         return userMutableLiveData;
    }

MutableLiveData只是LiveData的一個(gè)擴(kuò)展類帜乞,重寫了LiveData中的protected方法postValue()和setValue(),調(diào)用了super.postValue()和super.setValue(),也就是說(shuō)所有的方法都是在LiveData中實(shí)現(xiàn)

@SuppressWarnings("WeakerAccess")
public class MutableLiveData<T> extends LiveData<T> {
    @Override
    public void postValue(T value) {
        super.postValue(value);
    }
    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

先看 observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer)

flowerModel.getLiveData().observe(getActivity(), new Observer<FlowerModel.Data>() {
            @Override
            public void onChanged(@Nullable FlowerModel.Data data) {
                //update UI
                
            }
        });
...
 @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // 如果已經(jīng)銷毀就返回
            return;
        }
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        owner.getLifecycle().addObserver(wrapper);
    }
  • 在observe中首先判斷了當(dāng)前Lifecycler的狀態(tài),當(dāng)Destroy時(shí)即觀察者不處于活躍狀態(tài)筐眷,不用接收數(shù)據(jù)
  • 創(chuàng)建LifecycleBoundObserver實(shí)例保存?zhèn)魅氲腖ifecycleOwner和Observer黎烈,并保存在mObservers
  • 添加LifecycleOwner的觀察者,響應(yīng)生命周期的變化
    繼續(xù)看 LifecycleBoundObserver
 private abstract class ObserverWrapper {
        final Observer<T> mObserver;
        boolean mActive;
        int mLastVersion = START_VERSION;
        ObserverWrapper(Observer<T> observer) {
          //保存觀察者Observer
            mObserver = observer;
        }
        abstract boolean shouldBeActive();
        boolean isAttachedTo(LifecycleOwner owner) {
            return false;
        }
        void detachObserver() {
        }
        void activeStateChanged(boolean newActive) {
            if (newActive == mActive) {
                return;
            }
            // immediately set active state, 
            //so we'd never dispatch anything to inactive owner
            //立即設(shè)置活動(dòng)狀態(tài)匀谣,因此我們永遠(yuǎn)不會(huì)向非活動(dòng)所有者發(fā)送任何內(nèi)容
            mActive = newActive;
            boolean wasInactive = LiveData.this.mActiveCount == 0;
            LiveData.this.mActiveCount += mActive ? 1 : -1;
            if (wasInactive && mActive) {
                onActive();// 當(dāng)Activity/Fragment為活躍狀態(tài)時(shí)回調(diào)onActive()
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {
                onInactive(); // 當(dāng)Activity/Fragment未活躍狀態(tài)時(shí)回調(diào)onInactive()
            }
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
        @NonNull final LifecycleOwner mOwner;
        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
            super(observer);// 調(diào)用父類ObserverWrapper的構(gòu)造函數(shù)傳遞Owner
            mOwner = owner;
        }
        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
        // 實(shí)現(xiàn)GenericLifecycleObserver 當(dāng)生命周期改變時(shí)回調(diào)onStateChanged
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);// DESTROYED時(shí)移除觀察者
                return;
            }
            activeStateChanged(shouldBeActive());
        }
        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }
        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }
   
  • ObserverWrapper 在Owner活躍狀態(tài)改變時(shí)回調(diào)onActive和onInactive方法
  • LifecycleBoundObserver主要利用Lifecycler的生命周期觀察者GenericLifecycleObserver照棋,當(dāng)設(shè)置了owner.getLifecycle().addObserver(wrapper)后,當(dāng)生命周期改變時(shí)會(huì)回調(diào)onStateChange()方法武翎,在生命周期為Destroy時(shí)移除Observer

setValue(T value) (主線程)

@MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");//檢測(cè)是否在主線程
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }
...
 private void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
          //遍歷mObservers中所有的Observer烈炭,調(diào)用considerNotify()更新數(shù)據(jù)
                for (Iterator<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }
...
private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //更新數(shù)據(jù) 通過(guò)接口回調(diào)
        observer.mObserver.onChanged((T) mData);
    }
...
public interface Observer<T> {
    void onChanged(@Nullable T t);
}
...
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
public class DefaultTaskExecutor extends TaskExecutor {
    private final Object mLock = new Object();
    private ExecutorService mDiskIO = Executors.newFixedThreadPool(2);
    @Nullable
    private volatile Handler mMainHandler;

    @Override
    public void executeOnDiskIO(Runnable runnable) {
        mDiskIO.execute(runnable);
    }
    @Override
    public void postToMainThread(Runnable runnable) {
     //子線程向主線程發(fā)消息
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = new Handler(Looper.getMainLooper());
                }
            }
        }
        //noinspection ConstantConditions
        mMainHandler.post(runnable);
    }
    @Override
    public boolean isMainThread() {//檢測(cè)是否在主線程具體實(shí)現(xiàn)
        return Looper.getMainLooper().getThread() == Thread.currentThread();
    }
  • setValue()中先檢查是否主線程然后調(diào)用了dispatchingValue(),在dispatchingValue中遍歷mObservers中所有的Observer,調(diào)用considerNotify()中.mObserver.onChanged(T)更新數(shù)據(jù)
    postValue(T value)(子線程)
 protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
...
  private final Runnable mPostValueRunnable = new Runnable() {
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            //noinspection unchecked
            setValue((T) newValue);
        }
    };
  • postValue()中傳遞的Runnable 也是調(diào)用setValue() 只不過(guò)是通過(guò)handle在子線程向主線程發(fā)消息

5.展望

本次分享只是分析了ViewModel后频,LiveData 的大概源碼梳庆,與簡(jiǎn)單示例暖途,但其實(shí)在實(shí)際生產(chǎn)環(huán)境中卑惜,我們需要使用ViewModel與Repository連接網(wǎng)絡(luò)層,同時(shí)如果需要數(shù)據(jù)持久化還需要連接Room數(shù)據(jù)庫(kù)層驻售,通過(guò)ViewModel生成LiveData露久,UI層訂閱LiveData,真正的實(shí)現(xiàn)數(shù)據(jù)驅(qū)動(dòng)界面

再看一次架構(gòu)圖

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末欺栗,一起剝皮案震驚了整個(gè)濱河市毫痕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌迟几,老刑警劉巖消请,帶你破解...
    沈念sama閱讀 221,695評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異类腮,居然都是意外死亡臊泰,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,569評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門蚜枢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)缸逃,“玉大人,你說(shuō)我怎么就攤上這事厂抽⌒杵担” “怎么了?”我有些...
    開(kāi)封第一講書人閱讀 168,130評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵筷凤,是天一觀的道長(zhǎng)昭殉。 經(jīng)常有香客問(wèn)我,道長(zhǎng),這世上最難降的妖魔是什么挪丢? 我笑而不...
    開(kāi)封第一講書人閱讀 59,648評(píng)論 1 297
  • 正文 為了忘掉前任莽鸭,我火速辦了婚禮,結(jié)果婚禮上吃靠,老公的妹妹穿的比我還像新娘硫眨。我一直安慰自己,他們只是感情好巢块,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,655評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布礁阁。 她就那樣靜靜地躺著,像睡著了一般族奢。 火紅的嫁衣襯著肌膚如雪姥闭。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書人閱讀 52,268評(píng)論 1 309
  • 那天越走,我揣著相機(jī)與錄音棚品,去河邊找鬼。 笑死廊敌,一個(gè)胖子當(dāng)著我的面吹牛铜跑,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播骡澈,決...
    沈念sama閱讀 40,835評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼锅纺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了肋殴?” 一聲冷哼從身側(cè)響起囤锉,我...
    開(kāi)封第一講書人閱讀 39,740評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎护锤,沒(méi)想到半個(gè)月后官地,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,286評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡烙懦,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,375評(píng)論 3 340
  • 正文 我和宋清朗相戀三年驱入,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片修陡。...
    茶點(diǎn)故事閱讀 40,505評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡沧侥,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出魄鸦,到底是詐尸還是另有隱情宴杀,我是刑警寧澤,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布拾因,位于F島的核電站旺罢,受9級(jí)特大地震影響旷余,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扁达,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,873評(píng)論 3 333
  • 文/蒙蒙 一正卧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧跪解,春花似錦炉旷、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 32,357評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至图仓,卻和暖如春罐盔,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背救崔。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 33,466評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工惶看, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人六孵。 一個(gè)月前我還...
    沈念sama閱讀 48,921評(píng)論 3 376
  • 正文 我出身青樓纬黎,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親狸臣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子莹桅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,515評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容