源码分析LiveData根据其生命周期自动处理数据

在官方文档中是这样说的:
LiveData是一个可观察的数据持有者类。与常规observable不同的是LiveData可以关联Activity,Fragment,Services的生命周期。保证了当在组件的生命周期的发生变化是LiveData会发生更新。
使用LiveData的优点有:
1.确保了数据源与UI的一致: LiveData遵循观察者模式。Observer生命周期状态更改时,LiveData会通知 对象。您可以合并代码以更新这些Observer对象中的UI 。每次应用程序数据更改时,观察者都可以在每次更改时更新UI,而不是更新UI。
2.没有内存泄漏:绑定在Lifecycle对象上,生命周期结束,自动解除。
3.当Activity停止时,不会造成crash(官方文档的解释如下)
If the observer’s lifecycle is inactive, such as in the case of an activity in the back stack, then it doesn’t receive any LiveData events.
由于LiveData存在onActive和onInactive两种状态,当调用onActive表示有观察者,会接收Event的改变。
4.不需要我们去处理生命周期:由于是一个观察者,当UI组件的生命周期发生变化是,LiveData会自动的处理,不需要更多的考虑。
5.保持着最新的数据:如果生命周期变为非活动状态,则会在再次变为活动状态时接收最新数据。例如,后台活动在返回前台后立即收到最新数据。
6.适配设备配置变化:比如如屏幕旋转,立即收到上次的数据。
7.资源共享:是对LiveData的扩展,使用单例模式。
通过源码看LiveData有以上有点:

@MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        if(owner.getLifecycle().getCurrentState() != State.DESTROYED) {
            LiveData<T>.LifecycleBoundObserver wrapper = new LiveData.LifecycleBoundObserver(owner, observer);
            LiveData<T>.ObserverWrapper existing = (LiveData.ObserverWrapper)this.mObservers.putIfAbsent(observer, wrapper);
            if(existing != null && !existing.isAttachedTo(owner)) {
                throw new IllegalArgumentException("Cannot add the same observer with different lifecycles");
            } else if(existing == null) {
                owner.getLifecycle().addObserver(wrapper);
            }
        }
    }

可以看到,当调用observe方法是,Activity或者Fragment本身实现了LifecycleOwner接口,通过Lifecycle getLifecycle();拿到他们的Lifecycle,最后一句代码owner.getLifecycle().addObserver(wrapper);此时我们知道他内部调用和lifecycle的使用一样,通过订阅的方式,当组件生命周期结束后,解除订阅。在这里有一重要的是,在他调用观察者时。判断了生命周期是否结束。owner.getLifecycle().getCurrentState() != State.DESTROYED这样保证了当Activity销毁掉,不会导致Crash。
在内部有一个观察者专门检测组件的生命周期:

public void onStateChanged(LifecycleOwner source, Event event) {
          //当组件销毁了,直接移除观察者,否则调整LiveData的状态。
            if(this.mOwner.getLifecycle().getCurrentState() == State.DESTROYED) {
                LiveData.this.removeObserver(this.mObserver);
            } else {
                this.activeStateChanged(this.shouldBeActive());
            }
        }

移除观察者:

 @MainThread
    public void removeObserver(@NonNull Observer<T> observer) {
    //判断当前线程,没有在主线程直接抛出异常
        assertMainThread("removeObserver");
        LiveData<T>.ObserverWrapper removed = (LiveData.ObserverWrapper)this.mObservers.remove(observer);
        if(removed != null) {
            removed.detachObserver();
            removed.activeStateChanged(false);
        }
    }
    @MainThread
    public void removeObservers(@NonNull LifecycleOwner owner) {
        assertMainThread("removeObservers");
        Iterator var2 = this.mObservers.iterator();
        while(var2.hasNext()) {
            Entry<Observer<T>, LiveData<T>.ObserverWrapper> entry = (Entry)var2.next();
            if(((LiveData.ObserverWrapper)entry.getValue()).isAttachedTo(owner)) {
                this.removeObserver((Observer)entry.getKey());
            }
        }
    }

LiveData设置值:通过源码可以看到,有postValue和setValue两种,而postValue实在其他线程中设置,setValue在主线程中调用。

protected void postValue(T value) {
        Object var3 = this.mDataLock;
        boolean postTask;
        synchronized(this.mDataLock) {
            postTask = this.mPendingData == NOT_SET;
            this.mPendingData = value;
        }
        if(postTask) {
            ArchTaskExecutor.getInstance().postToMainThread(this.mPostValueRunnable);
        }
    }

    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        ++this.mVersion;
        this.mData = value;
        this.dispatchingValue((LiveData.ObserverWrapper)null);
    }
LiveData如何在实际应用中使用

在代码中,LiveData如何通过观察者来实时更新的,相当于Handler一样,通过postValue()发布,在onChanged订阅者实时更新。

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_view_model_test1);
        btCurrSend = (Button) findViewById(R.id.bt_curr_send);
        btNextSend = (Button) findViewById(R.id.bt_next_send);
        btCurrSend.setOnClickListener(this);
        btNextSend.setOnClickListener(this);
        
        testViewModel = ViewModelProviders.of(this).get(TestViewModel.class);
        mutableLiveData = testViewModel.getData();
        mutableLiveData.observe(this, new Observer<String>() {
            @Override
            public void onChanged(@Nullable String s) {
                btNextSend.setText(mutableLiveData.getValue());
            }
        });
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.bt_curr_send:
                mutableLiveData.setValue("点击按钮后效果************************");
                break;
            case R.id.bt_next_send:
                new Thread() {
                    @Override
                    public void run() {
                        mutableLiveData.postValue("点击按钮后效果-------------");
                    }
                }.start();
                break;
        }
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值