Jetpack第三篇:LiveData

作者: AxeChen | 来源:发表于2021-12-13 00:44 被阅读0次

    本文来自微信公众号“轻安易卓”,转载请注明作者

    1、什么是LiveData

    基于观察者的消息订阅/分发组件,依靠Lifecycles确保LiveData的数据仅分发给处于活跃状态的观察者。

    2、LiveData的使用

    • 导入依赖
    implementation  'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
    

    LiveData在实战中一般都是作为网络请求的数据分发,LiveData本身就是一个观察者模式,在实战中,网络请求的时候,LiveData便将数据分发出去。

    MutableLiveData继承了LiveData,一般都用MutableLiveData来做数据分发使用。还有一种MediatorLiveData也继承了LiveData,后面会讲到。

    • MutableLiveData使用
    
    class MainActivity : AppCompatActivity() {
      var liveData1: MutableLiveData<Int> = MutableLiveData()
      var liveData2: MutableLiveData<String> = MutableLiveData()
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
          // 注册观察者
          startObserver()
          // 数据发生改变
          liveData1.postValue(1000)
          liveData2.postValue("33333")
      }
      private fun startObserver() {
          liveData1.observe(this, Observer {
              Log.i("liveData1",it.toString())
          })
          liveData2.observe(this, Observer {
              Log.i("liveData2",it.toString())
          })
      }
    }
    

    结果:

    10-17 05:52:45.645 4197-4197/com.mg.axechen.testdemo I/liveData1: 1000
    10-17 05:52:45.645 4197-4197/com.mg.axechen.testdemo I/liveData2: 33333
    
    • MediatorLiveData
      MediatorLiveData可以通过addSource将所有的MutableLiveData统一观察,当然他自己也是继承了LiveData,也可以被其他的Observer观察。
    
    class MainActivity : AppCompatActivity() {
      var liveData1: MutableLiveData<Int> = MutableLiveData()
      var liveData2: MutableLiveData<String> = MutableLiveData()
      var mediatorLiveData: MediatorLiveData<Any> = MediatorLiveData()
      override fun onCreate(savedInstanceState: Bundle?) {
          super.onCreate(savedInstanceState)
          setContentView(R.layout.activity_main)
          mediatorLiveData.addSource(liveData1,dataObserver2)
          mediatorLiveData.addSource(liveData2,dataObserver)
          mediatorLiveData.observe(this, Observer {
              Log.i("liveData5",it.toString())
          })
          liveData1.value = 1000
          liveData2.value = "axeChen"
          mediatorLiveData.postValue("xxxx")
      }
      private var dataObserver2 = object :Observer<Int>{
          override fun onChanged(t: Int?) {
              Log.i("liveData4",t.toString())
          }
      }
      private var dataObserver =object :Observer<Any> {
          override fun onChanged(t: Any?) {
              Log.i("liveData3",t.toString())
          }
      }
    }
    

    输出结果:

    10-17 06:02:21.624 4713-4713/com.mg.axechen.testdemo I/liveData4: 1000
    10-17 06:02:21.624 4713-4713/com.mg.axechen.testdemo I/liveData3: axeChen
    10-17 06:02:21.637 4713-4713/com.mg.axechen.testdemo I/liveData5: xxxx
    

    3、LiveData源码解析

    3.1、LiveData的关键类

    LiveData

    public abstract class LiveData<T> {}
    

    类声明可以看出这个是一个抽象类,它封装了订阅和取消订阅的方法:

    // 订阅Observer的方法
    public void observe(@NonNull LifecycleOwner owner, 
                           @NonNull Observer<? super T> observer) {}
    public void observeForever(@NonNull Observer<? super T> observer) {}  
    
    // 取消订阅Observer的方法
    public void removeObserver(@NonNull final Observer<? super T> observer) {}
    public void removeObservers(@NonNull final LifecycleOwner owner) {}
    

    封装了Observerapper的子类LifecycleBoundObserver和AlwaysActiveObserver,关于Observerapper这个类,只要知道这个是用于分发数据的类,具体如何分发下面会分析到。

    class LifecycleBoundObserver extends
     ObserverWrapper implements LifecycleEventObserver {} 
     private class AlwaysActiveObserver extends ObserverWrapper {}
    

    LifecycleBoundObserver
    生命周期安全的Observer。

    class LifecycleBoundObserver extends
     ObserverWrapper implements LifecycleEventObserver {}
    

    AlwaysActiveObserver
    非生命周期的Observer。

    private class AlwaysActiveObserver extends ObserverWrapper {}
    
    3.2、关键方法

    两种订阅方式
    上面提到了生命周期安全的概念,最大的区别就是在分发数据的时候是否考虑到了生命周期。考虑和非考虑生命周期安全的方式订阅的方式也不一样。
    LiveData中observer方法是考虑生命周期安全的订阅方式。
    observer考虑生命周期安全的方式订阅

    @MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
      // 1、判断是否在主线程中
            assertMainThread("observe");
            // 2、判断当前宿主状态是不是Destory,假如是Destory则直接return
            if (owner.getLifecycle().getCurrentState() == DESTROYED) {
                // ignore
                return;
            }
            // 3、封装成LifecycleBoundObserver ,
            LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
            // 4、判断是否已经存在了Observer
            ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
            // 5、假日已经存在了Observer则抛出异常
            if (existing != null && !existing.isAttachedTo(owner)) {
                throw new IllegalArgumentException("Cannot add the same observer"
                        + " with different lifecycles");
            }
            if (existing != null) {
                return;
            }
            // 6、订阅观察者
            owner.getLifecycle().addObserver(wrapper);
        }
    

    看下LifecycleBoundObserver的代码,onStateChanged是分发状态的方法。

    
    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() {
            // 这里用了状态枚举的比较方法,去看isAtLeast方法就会明白,
            // 只有当状态为STARTED或者RESUMED算为活跃状态,返回true
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }
    
        @Override
        public void onStateChanged(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            // 1、获取当前宿主的生命周期状态
            Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
            
            // 2、判断状态是不是Destory
            if (currentState == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            // 3、while阻塞线程
            Lifecycle.State prevState = null;
            while (prevState != currentState) {
                prevState = currentState;
                activeStateChanged(shouldBeActive());
                currentState = mOwner.getLifecycle().getCurrentState();
            }
        }
    
        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }
    
        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }
    

    activeStateChanged,中传入是不是宿主是不是活跃的状态。如果是活跃状态则调用dispatchingValue。

    void activeStateChanged(boolean newActive) {
        if (newActive == mActive) {
            return;
        }
        // immediately set active state, so we'd never dispatch anything to inactive
        // owner
        mActive = newActive;
        changeActiveCounter(mActive ? 1 : -1);
        if (mActive) {
            // 分发值
            dispatchingValue(this);
        }
    }
    

    不考虑生命周期安全的observerForver

    observerForver和observer最大的区别就是没有传入LifecycleOwner,不会考虑生命周期的变化。只要数据发生变化时就会进行数据回调。

    
    @MainThread
    public void observeForever(@NonNull Observer<? super T> observer) {
        // 1、判断是不是主线程
        assertMainThread("observeForever");
        // 2、封装成AlwaysActiveObserver
        AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
        // 3、判断是不是已经存在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;
        }
        // 4、回调数据
        wrapper.activeStateChanged(true);
    }
    
    @SuppressWarnings("WeakerAccess") /* synthetic access */
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                // 当initiator 不为空就将这发送给自己,这个在Observer注册的时候会调用
                considerNotify(initiator);
                initiator = null;
            } else {
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                       // 遍历所有的Observer并分发数据
                     considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }
    

    AlwaysActiveObserver
    最终分发数据的方法是considerNotify

    private class AlwaysActiveObserver extends ObserverWrapper {
    
        AlwaysActiveObserver(Observer<? super T> observer) {
            super(observer);
        }
    
        @Override
        boolean shouldBeActive() {
            // 永久返回True
            return true;
        }
    }
    
    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;
        }
        // 同步Version
        observer.mLastVersion = mVersion;
        // 分发数据
        observer.mObserver.onChanged((T) mData);
    }
    

    从AlwaysActiveObserver可以看到,shouldBeActive()永久为true。只要有数据就会立即回调。
    代码中已经非常明白了,先判断是不是处于活跃状态。然后再分发数据。

    3.3、移除订阅

    这个就是将订阅移除掉

    @MainThread
    public void removeObserver(@NonNull final Observer<? super T> observer) {
        assertMainThread("removeObserver");
        ObserverWrapper removed = mObservers.remove(observer);
        if (removed == null) {
            return;
        }
        removed.detachObserver();
        removed.activeStateChanged(false);
    }
    
    @MainThread
    public void removeObservers(@NonNull final LifecycleOwner owner) {
        assertMainThread("removeObservers");
        for (Map.Entry<Observer<? super T>, ObserverWrapper> entry : mObservers) {
            if (entry.getValue().isAttachedTo(owner)) {
                removeObserver(entry.getKey());
            }
        }
    }
    
    3.4、PostValue()、setValue()

    从一开始的例子可以知道,如果调用了这两个方法,liveData.observer{}就可以观察到值的变化,从而获取到新的值。这两个方法是更新LiveData值的方法。

    protected void postValue(T value) {
        boolean postTask;
        synchronized (mDataLock) {
            postTask = mPendingData == NOT_SET;
            mPendingData = value;
        }
        if (!postTask) {
            return;
        }
        ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
    }
    
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }
    

    这两个的区别:

    • 1、setValue只能在主线程中调用。
    • 2、postValue能在子线程中调用,具有同步锁的功能。
    • 3、postValue多次调用只有最后一个值才有效。

    4、总结

    LiveData使用的时候会根据宿主是不是活跃去分发数据,减少了一些因为Activity,Fragment不可见而处理数据,浪费了资源的情况,使用时尽量使用安全的订阅方式和postValue方法。

    相关文章

      网友评论

        本文标题:Jetpack第三篇:LiveData

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