LiveData的基本使用以及源码分析

LiveData存在的意义

LiveData是jetpack提供的一种响应式编程组件,它可以包含任何类型的数据,并在数据发生变化的时候通知给观察者,一般与ViewModel结合起来使用。

LiveData的基本使用

  • 通常与ViewModel一起使用,一般情况下只需要声明的数据类型定义为MutableLiveData<>,通过setValue(),getValue(),以及postValue()对数据进行操作,

setValue()用于给LiveData设置数据,但是只能在主线程中进行调用
postValue()用于在非主线程给LiveData设置数据

  • 通过数据的observer对数据进行观察,然后对每次变化进行相应的操作
private MutableLiveData<String> infos;

public MutableLiveData<String> getInfo(){
        if (infos == null){
            infos = new MutableLiveData<>();
        }
        return infos;
    }
    
button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                int x = myViewModel.increaseNumber();
                myViewModel.getInfo().setValue("info = " + x);
            }
        });
        
myViewModel.getInfo().observe(this, new Observer<String>() {
            @Override
            public void onChanged(String s) {
                textView.setText(s);
            }
        });

源码分析

LiveDate是一个抽象类,所以我们在使用的时候不能直接生成他的实例,所以我们常使用它的实现类Mutable LiveData()

public class MutableLiveData<T> extends LiveData<T> {

    public MutableLiveData(T value) {
        super(value);
    }

    public MutableLiveData() {
        super();
    }

    @Override
    public void postValue(T value) {
        super.postValue(value);
    }

    @Override
    public void setValue(T value) {
        super.setValue(value);
    }
}

setValue()

首先看一下setValue()

//保证了多线程数据的可见性
private volatile Object mData;
protected void setValue(T value) {
        assertMainThread("setValue");
        //使用mVersion的增加代表数据的改变
        mVersion++;
        //进行赋值
        mData = value;
        //分发数据变化,调用回调函数
        dispatchingValue(null);
    }

看一下分发数据的具体实现:

void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            //observerWrapper不为空,使用considerNotify()通知特定的观察者
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
            //observerWrapper为空,遍历通知所有的观察者
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                     //这里mDispatchInvalidated 为true,表示在while循环未结束的时候,
                     //有其他数据发生变化,并调用了该函数
                    //在上面的if判断中设置了 mDispatchInvalidated = true,
                    // 结束本次for循环,没有退出while循环,开始下一次for循环
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }
 private void considerNotify(ObserverWrapper observer) {
        if (!observer.mActive) {
            return;
        }
       //如果不是调用的observerForever方法
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        //如果数据没有发生改变则返回
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        //数据发生改变,则更新mLastVersion数据,并调用observer的onChanged方法,也就是
        //在使用过程中重写的方法。
        observer.mLastVersion = mVersion;
        observer.mObserver.onChanged((T) mData);
    }

postValue()

用于在子线程中给liveData设置数据

private final Runnable mPostValueRunnable = new Runnable() {
        @SuppressWarnings("unchecked")
        @Override
        public void run() {
            Object newValue;
            synchronized (mDataLock) {
                newValue = mPendingData;
                mPendingData = NOT_SET;
            }
            setValue((T) newValue);
        }
    };
protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        //
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }

先看一下ArchTaskExecutor的postToMainThread,其实最终调用的是DefaultTaskExecutor的postToMainThread方法, 最终创建一个主线程的handler。

public void postToMainThread(Runnable runnable) {
        if (mMainHandler == null) {
            synchronized (mLock) {
                if (mMainHandler == null) {
                    mMainHandler = createAsync(Looper.getMainLooper());
                }
            }
        }
        //noinspection ConstantConditions
        mMainHandler.post(runnable);
    }

postValue最终也是调用setValue来进行数据设置。


observe(LifecycleOwner, Observer)

 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);
    }

如果当前的Activity/Fragment 处于DESTROYED状态则直接返回,否则新建LifecycleBoundObserver对象,并和Activity/Fragment的生命周期建立关系,当生命周期发生变化的时候就会调用wrapper中的 onStateChanged方法。


LifecycleBoundObserver

 class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }

        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
        //当生命周期发生变化的时候,调用此方法
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }

      ···
    }

当Activity/Fragment的生命周期发生变化时,最终会调用activeStateChanged方法。

activeStateChanged()方法的主要逻辑是:如果当前的lifecycleOwner处于STARTED或者RESUMED状态时则调用dispatchingValue()方法

 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;
             // 处于 active 状态的 observer 数量从0 -> 1时,触发 onActive() 方法
            if (wasInactive && mActive) {
            //空方法可以自定义实现
                onActive();
            }
            // 处于 active 状态的 observer 数量从 1 -> 0时,触发 onInactive() 方法
            if (LiveData.this.mActiveCount == 0 && !mActive) {
            //空方法,可自定义实现
                onInactive();
            }
            // observer 从  inactive -> active 时, 更新数据
            if (mActive) {
                dispatchingValue(this);
            }
        }

而dispatchingValue方法在setValue中已经分析过了,这里不再多做解释。


observeForever

public void observeForever(@NonNull Observer<? super T> observer) {
        assertMainThread("observeForever");
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        if (existing instanceof LiveData.LifecycleBoundObserver) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        if (existing != null) {
            return;
        }
        wrapper.activeStateChanged(true);
    }

无论ObserverOwner的生命周期状态时怎样的,如果数据改变都会调用重写的onChanged()方法。


源码总结

  • 使用observer观察数据时

向LifecycleOwner中添加一个带有lifecycle Owner的Observer也就是Lifecycle BoundObserver
当LIfecycle Owner的生命周期发生变化的时候就会调用onStatedChanged方法,进一步调用了active StateChanged方法
判断Lifecycle Owner的状态如果是STARED或者RESUNMED则调用considerNotify方法
判断数据是否发生变化,如果发生变化,则调用重写的onChanged()方法。

  • 设置LiveData 数据时

数据版本号加1
如果是在非主线程则切换到主线程,然后遍历所有的Observer,根据版本号判断数据是否发生了变化,如果数据发生了变化,则将数据分发给处于 active 状态的Observer,并调用相应的onChanged()方法。


注意事项

(1)如果观察者(由 Observer 类表示)的生命周期处于 STARTED 或 RESUMED 状态,则 LiveData 会认为该观察者处于活跃状态。LiveData 只会将更新通知给活跃的观察者。为观察 LiveData 对象而注册的非活跃观察者不会收到更改通知。

(2)使用LiveData的好处:

  • 确保界面符合数据状态
    LiveData 遵循观察者模式。当底层数据发生变化时,LiveData 会通知 Observer 对象。您可以整合代码以在这些 Observer 对象中更新界面。这样一来,您无需在每次应用数据发生变化时更新界面,因为观察者会替您完成更新。
  • 不会发生内存泄漏
    观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。
  • 不会因 Activity 停止而导致崩溃
    如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。
  • 不再需要手动处理生命周期
    界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
  • 数据始终保持最新状态
    如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
  • 适当的配置更改
    如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。
  • 共享资源
    您可以使用单例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象。如需了解详情,请参阅扩展 LiveData。

(3)一般会在OnCreate()中对LiveData对象开始进行观察,原因如下:

  • 确保系统不会从 Activity 或 Fragment 的 onResume() 方法进行冗余调用。
  • 确保 Activity 或 Fragment 变为活跃状态后具有可以立即显示的数据。一旦应用组件处于 STARTED 状态,就会从它正在观察的 LiveData 对象接收最新值。只有在设置了要观察的 LiveData 对象时,才会发生这种情况。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值