Jetpack使用(二)LiveData核心原理

LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。

  • 活跃状态:STARTED 或 RESUMED状态
    因为LiveData只会更新处于前台的activty的数据,所以LiveData具有以下

优点

  • 不会发生内存泄露
    观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。
  • 不会因 Activity 停止而导致崩溃
    如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。
  • 不再需要手动处理生命周期
    界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
  • 数据始终保持最新状态
    如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。

具体使用

  • 创建 LiveData 对象
public class NameViewModel extends ViewModel {
    private MutableLiveData currentName;
    public MutableLiveData getCurrentName(){
        if(currentName==null){
            currentName=new MutableLiveData<>();
        }
        return currentName;
    }
}
  • 观察 LiveData 对象
    public class NameActivity extends AppCompatActivity {

        private NameViewModel model;

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // Other code to setup the activity...

            // Get the ViewModel.
            model = ViewModelProviders.of(this).get(NameViewModel.class);

            // Create the observer which updates the UI.
            final Observer nameObserver = new Observer() {
                @Override
                public void onChanged(@Nullable final String newName) {
                    // Update the UI, in this case, a TextView.
                    nameTextView.setText(newName);
                }
            };

            // Observe the LiveData, passing in this activity as the LifecycleOwner and the observer.
            model.getCurrentName().observe(this, nameObserver);
        }
    }
  • 更新 LiveData 对象
 btn.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                String anotherName="小三爷";
                model.getCurrentName().setValue(anotherName);
            }
        });

注意:setValue在主线程使用;postValue在子线程使用

源码分析

我们从observe做为入口

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

一开始先判断observe观察者是不是在主线程,不是在在主线程就会报异常,
然后获得被观察者的生命周期,我们这里是actvity,然后判断是不是处于DESTROYED状态,如果处于DESTROYED直接返回,然后通过使用LifecycleBoundObserver把观察者和被观察者包装在一起,然后再把wrapper放到mObservers集合里,最后通过addObserver添加观察者,把观察者和被观察者的关系建立起来。
关系建立好之后,我们去看是怎么发送数据的,我们看到setValue的源码

 @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }

这个这个方法也是在主线程里调用的,一开始也判断是不是主线程,然后mVersion版本++,这个变量后面再看,再把value存到LiveData的成员变量mData里,然后我们看到dispatchingValue方法里面,

  @SuppressWarnings("WeakerAccess") /* synthetic access */
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                for (Iterator, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

因为第一次传的是空,所以走到for循环里面,通过迭代器从mObservers取出每个观察者,然后调用considerNotify真正发送通知,


 @SuppressWarnings("unchecked")
    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);
    }

一开始observer如果不是活跃状态(STARTED 或 RESUMED状态)直接退出,再判断是不是应该被激活,如果不应该被激活,我们看看shouldBeActive方法

 @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

我们看到这个方法就是判断状态是不是大于等于STARTED,通过上一篇文章我们知道,比STARTED大的就是RESUMED,所以这里只有是状态STARTED或者RESUMED的时候才是返回 true的,所以这个if也就是判断是不是处于活跃状态,如果不是活跃状态进入activeStateChanged方法,

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;
            if (wasInactive && mActive) {
                onActive();
            }
            if (LiveData.this.mActiveCount == 0 && !mActive) {
                onInactive();
            }
            if (mActive) {
                dispatchingValue(this);
            }
        }
    }

这里就是在统计LiveData里有没有活跃状态的,如果有就执行dispatchingValue,这次传的就不是null了,而是具体的liveData对象了,所以又走到之前的dispatchingValue方法里,只是这次走的是不为null的判断里,所以,这次再走到 if (observer.mLastVersion >= mVersion) {这个判断里,我们知道mLastVersion和mVersion初始值都是-1,但之前mVersion++了,不会return,所以最后,执行observer.mObserver.onChanged((T) mData);发送之前存的mData数据的操作。

  • 注意: if (initiator != null) 参数传null和不传null的区别就是如果传null将会通知所有的观察者,反之仅仅通知传入的活跃的观察者
    至此,我们LiveData的原理分析完了。

总结:LiveData通过addObserver绑定到Lifecycles上,所以拥有了感应生命周期的能力,而且LiveData只会去更新处于活跃状态的应用组件观察者,如果界面还在后台,LiveData是不会去发送数据的,这样做大大提高了app的性能。

阅读全文
下载说明:
1、本站所有资源均从互联网上收集整理而来,仅供学习交流之用,因此不包含技术服务请大家谅解!
2、本站不提供任何实质性的付费和支付资源,所有需要积分下载的资源均为网站运营赞助费用或者线下劳务费用!
3、本站所有资源仅用于学习及研究使用,您必须在下载后的24小时内删除所下载资源,切勿用于商业用途,否则由此引发的法律纠纷及连带责任本站和发布者概不承担!
4、本站站内提供的所有可下载资源,本站保证未做任何负面改动(不包含修复bug和完善功能等正面优化或二次开发),但本站不保证资源的准确性、安全性和完整性,用户下载后自行斟酌,我们以交流学习为目的,并不是所有的源码都100%无错或无bug!如有链接无法下载、失效或广告,请联系客服处理!
5、本站资源除标明原创外均来自网络整理,版权归原作者或本站特约原创作者所有,如侵犯到您的合法权益,请立即告知本站,本站将及时予与删除并致以最深的歉意!
6、如果您也有好的资源或教程,您可以投稿发布,成功分享后有站币奖励和额外收入!
7、如果您喜欢该资源,请支持官方正版资源,以得到更好的正版服务!
8、请您认真阅读上述内容,注册本站用户或下载本站资源即您同意上述内容!
原文链接:https://www.dandroid.cn/archives/19477,转载请注明出处。
0

评论0

显示验证码
没有账号?注册  忘记密码?