美文网首页
jetpack系列之Lifedata

jetpack系列之Lifedata

作者: gogoingmonkey | 来源:发表于2021-08-10 21:08 被阅读0次

    目录结构

    1.背景及livedata优劣势
    2.livedata简单使用
    3.livedata实现原理

    1.背景及优劣势

    1.优势1 感知生命周期UI活跃才刷新UI

    比较常见的场景是当网络请求结果回来的时候,经常需要判断 Activity 或者 Fragment 是否已经 Destroy, 如果不是 destroy,才更新 UI

    2.防止内存泄漏

    livedata是在lifecycle基础上实现,当对应的Lifecycle销毁,会自动解除livedata和被观察者,比如activity的绑定关系,避免内存泄漏

    3.防止数据丢失

    LiveData在横竖屏切换等Configuration改变时,也能保证获取到最新数据。实现原理我们在后面的文章里面详细说。

    2.简单使用

    LiveData 是一个抽象类,它的实现子类有 MutableLiveData ,MediatorLiveData。常用的是 MutableLiveData。他常常结合 ViewModel 使用
    依赖添加:

    implementation "android.arch.lifecycle:livedata:1.1.0"
    
    1.在viewmodle中创建 livedata
    public class NameViewModel extends ViewModel {
        private MutableLiveData<String> currentName;
        public MutableLiveData<String> getCurrentName(){
            if(currentName==null){
                currentName=new MutableLiveData<>();
            }
            return currentName;
        }
    }
    
    2.在被观察者中建立联系

    通过ViewModelProviders 获取到Viewmodel然后调用model中方法调用observe传入被观察者和观察回调 ,当有变化,就会调用到onChanged方法

            //需要一个观察者来观察数据
            Observer observer=new Observer<String>(){
                @Override
                public void onChanged(String s) {
                    nameTextView.setText(s);
                }
            };
            //获取到viewmodel
            model= ViewModelProviders.of(this).get(NameViewModel.class);
            //取出livedata完成订阅
            model.getCurrentName().observe(this,observer);
    

    接收事件LiveData提供了两种添加观察者的方法:observeForever()、observe()。使用observeForever()这个还必须手动调用remove方法移除,使用该方法 就不会管被观察者是否处于活跃状态。

    3.发送事件

    当需要变化,调用viewmodel 的setvalue 或者postvalue放松更新数据 ,比如下面我直接在一个按钮点击事件中,触发。
    两者区别:

    • setValue()要在主线程中调用, 实际上是会在调用 serValue 方法的线程回调
    • postValue()既可在主线程也可在子线程中调用。
    btn.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v) {
                    model.getCurrentName().postValue("XXX");
                }
            });
    

    3.源码分析

    1.先看livedata类的observe方法

    我们在被观察者类中,调用MutableLiveData的observe方法,这个类里面定义了set postValue方法,观察方法还是在Livedata中实现:首先判断是在主线程,否则抛出异常,然后再判断当前被观察的对象状态,如果是DESTROYED状态那么return 然后封装放到一个安全的map中并绑定wrapper作为观察者,最后一行代码,还是调用lifecycle的addobserver(观察者)绑定生命周期观察。

    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);
        }
    
    2.绑定后使用setValue与postValue通知观察者

    可以看到下面代码最后一行里,还是调用的主线程handler实现切换到主线程,最后调用setValue

    protected void postValue(T value) {
            boolean postTask;
            synchronized (mDataLock) {
                postTask = mPendingData == NOT_SET;
                mPendingData = value;
            }
            if (!postTask) {
                return;
            }
            ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
        }
    
    
    3.在setValue方法中调用dispatchingValue

    分发value里回调用到considerNotify(initiator)方法

        private void considerNotify(ObserverWrapper observer) {
            if (!observer.mActive) {
                return;
            }
            // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
            //
            // we still first check observer.active to keep it as the entrance for events. So even if
            // the observer moved to an active state, if we've not received that event, we better not
            // notify for a more predictable notification order.
            if (!observer.shouldBeActive()) {
                observer.activeStateChanged(false);
                return;
            }
            if (observer.mLastVersion >= mVersion) {
                return;
            }
            observer.mLastVersion = mVersion;
            observer.mObserver.onChanged((T) mData);
        }
    

    这个方法中主要是应该被激活状态下,调用观察者的onChanged方法 ,这样就回到我们被观察者中创建的观察回调。

    相关文章

      网友评论

          本文标题:jetpack系列之Lifedata

          本文链接:https://www.haomeiwen.com/subject/sayfbltx.html