JetPack组件介绍

LiveData

LiveData是一个数据持有类,它可以通过添加观察者被其他组件观察其变更。不同于普通的观察者,它最重要的特性就是可以感知应用程序的生命周期,如在Activity中如果数据更新了但Activity已经是destroy状态,LivaeData就不会通知Activity(observer)。
LiveData感知生命周期的原理,是因为它实现了LifecycleObserver接口。


生命周期感知原理

生命周期的感知,是通过ComponentActivty中注入的ReportFragment实现的。在ReportFragment的生命周期函数调用时,会通过LifecycleRegistry通知所有注册的LifecycleObserver接口实现。

相较于功能类似的ObservableField,livedata还有以下优势:
1,ObservableField只有在数据发生改变时UI才会收到通知,而LiveData不同,只要你postValue或者setValue,UI都会收到通知,不管数据有无变化,
2,LiveData能感知Activity的生命周期,在Activity不活动的时候不会触发,例如一个Activity不在任务栈顶部

ViewModel

ViewModel同样是一个生命周期组件,它不会受Activity横竖屏切换导致的销毁重建影响,而是在Activity生命周期内一直存在。这种特性在实际中主要用来获取Model层的数据,因为这样就不需要频繁地重建连接,也不需要编写状态保存代码。
ViewModel生命周期的特性,其实是依靠FragmentActivity中ViewModelStore的生命周期特性而来的,具体请见图:


ViewModel和AppCompatActivity的关系

ViewModelProviders其实是把创建的ViewModel通过Map容器保存在了FragmentActivity的成员变量ViewModelStore中,依靠FragmentActivity本身的能力实现了ViewModel的生命周期特性。那么FragmentActivity是怎么保存ViewModelStore的呢?

保存ViewModelStore

其实当Activity横竖屏转换时,FragmentActivity会new一个包含当前ViewModelStore信息的NonConfigurationInstances,并使用ActivityClientRecord,通过Binder将NonConfigurationInstances发往服务端的ActivityRecord进行保存。

ViewModelStore销毁

Activity销毁时,其实其中保存的ViewModelStore也是会被销毁的。

ViewModelStore恢复

当Activity重新构建时,会再向ActivityRecord获取包含销毁前ViewModelStore信息的NonConfigurationInstances。这样新的Activity就拥有了之前的ViewModelStore,看起来就好像经历了Activity横竖屏转换的ViewModel一直存在一样。

ViewModel结合LiveData使用

LiveData通常会配合ViewModel来使用,ViewModel负责触发数据的更新,更新会通知到LiveData,然后LiveData再通知活跃状态的观察者。
LiveData由ViewModel创建,它内含数据源和UI响应数据变化的回调Observer。回调通过LiveData的observe函数传入:

    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        assertMainThread("observe");
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            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);
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容