Android Jetpack Components of LiveData 学习笔记

Android Jetpack Components of Lifecycle 学习笔记

Android Jetpack Components of LiveData 学习笔记

Android Jetpack Components of ViewModel 学习笔记

Demo 地址:https://github.com/mengzhinan/Lifecycle_LiveData_ViewModel_demo

LiveData Google 文档:https://developer.android.google.cn/topic/libraries/architecture/livedata

环境配置:

与 Lifecycle 一样,如果是 sdk 小于 26 的版本,需要导入依赖包 android.arch.lifecycle。现在新建的项目默认都是 28 了,故不需要任何配置。

扫描二维码关注公众号,回复: 12584921 查看本文章

LiveData 是什么?

LiveData is an observable data holder class. Unlike a regular observable, LiveData is lifecycle-aware, meaning it respects the lifecycle of other app components, such as activities, fragments, or services. This awareness ensures LiveData only updates app component observers that are in an active lifecycle state.

LiveData 是一个可观察的数据持有者类。与常规 Observable 不同,LiveData 是生命周期感知的,这意味着它尊重其他应用程序组件的生命周期,例如 Activity,Fragment 或 Service。此感知确保 LiveData 仅更新处于活动生命周期状态的应用程序组件观察者。

简单实用:

先来一个 Demo 简述 LiveData 的使用。

public class DataUtil {

    private MutableLiveData<String> name = new MutableLiveData<>();

    public LiveData<String> getNameLiveData(){
        return name;
    }

    public void requestHead() {
        // 模拟请求网络或 DB,然后更新数据
        name.setValue("requestHead success");
    }

    public void requestList() {
        // 模拟请求网络或 DB,然后更新数据
        name.setValue("requestList success");
    }

}
public class LiveDataActivity extends AppCompatActivity {

    private DataUtil dataUtil;

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

        dataUtil = new DataUtil();
        dataUtil.getNameLiveData().observe(this, data -> {
            // 得到数据更新



        });
    }

    @Override
    protected void onResume() {
        super.onResume();
        dataUtil.requestHead();
        dataUtil.requestList();
    }
}

代码说明:

抱歉,Demo 代码中的命名很随意。

在 DataUtil 类中定义了一个 MutableLiveData<String> 类型的对象 name,name 是一个使用字符串类型数据的对象。

在 DataUtil 中定义了 requestHead() 和 requestList() 两个方法,用来模拟网络请求。并在其中模拟网络请求成功,同时更新 name 对象中的值。

在 LiveDataActivity 中,注意其父类是 AppCompatActivity。

在 LiveDataActivity 中创建 DataUtil 对象,并获取到其中的 LiveData 对象 name,在 name 上注册观察者。

在适当的位置,比喻页面 onResume 或 onClick,调用  DataUtil 对象的  requestHead() 或 requestList() 方法。待 name 对象中的数据有变更时,LiveDataActivity.DataUtil.MutableLiveData<String> 中注册的观察者就有收到数据变更通知。

在整个 LiveData 生命周期内,name 对象会持有一个字符串对象值。当 name 中的值发生变化时,会通知所有观察者对象。

通过上面的描述,应该能理解官方的解释了。

LiveData 优点:

1、便于使 Activity 中的 UI 逻辑和网络请求分离解耦。

2、LiveData 不会有内存泄漏的风险。

LiveData 原理简述:

上例中,为什么使用的是 MutableLiveData?

通过查看源码发现,MutableLiveData 继承 LiveData。目的是为了对外暴漏 postValue()、 setValue() 两个方法。二者的区别是 postValue() 可以在非 UI 线程中调用,然后会通过 handler 切换到 UI 线程中。

我们从 MutableLiveData 的 setValue() 方法分析,为什么 setValue() 后,数据会更新到 Activity 中的观察者中。

追索到 LiveData 的 setValue() 方法中:

@MainThread
protected void setValue(T value) {
    // 检查线程,如果是子线程,会直接抛异常
    assertMainThread("setValue");
    mVersion++;
    // 暂存数据
    mData = value;
    // 分发数据更改
    dispatchingValue(null);
}

追查方法 dispatchingValue(null);

private 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<Map.Entry<Observer<T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }

循环所有观察者集合,逐个分发消息。追查方法 considerNotify(iterator.next().getValue());

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;
        //noinspection unchecked
        observer.mObserver.onChanged((T) mData);
    }

最后调用了 Observer 的 onChanged() 方法,通知到了观察者。注意 observer 能感知组件的生命周期,可以看看 ObserverWrapper 的子类 LifecycleBoundObserver。

我们在从 LiveDataActivity 中的注册观察者开始分析:

追索到 LiveData 的 observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) 方法:

@MainThread
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
        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);
    }

传递进来的 observer 都被包装成了 LifecycleBoundObserver 类型。

注意这行代码:

owner.getLifecycle().addObserver(wrapper);

获取 owner 对象,并注册了 Lifecycle 的观察者对象。这不是上一篇文章讲的 Livecycle 内容吗?

难怪上面说 LiveData 是可以感知组件生命周期的。

至此,已经完全解释了 LiveData 数据更新的原理,以及生命周期感知的原理。

Demo 地址:https://github.com/mengzhinan/Lifecycle_LiveData_ViewModel_demo

猜你喜欢

转载自blog.csdn.net/fesdgasdgasdg/article/details/100119688