LiveData

2020-01-05  本文已影响0人  主音King

LiveData:数据持有类
·数据可以被观察者订阅
·observe()能够感知组件(Fragment、Activity、Service)生命周期
·observe()只有在组件处于激活状态(STARTED、RESUMED)才会通知观察者有数据更新
·observeForever()观察者会一直收到数据的变化回调,而不是在组件STARTED和RESUME状态下才会收到。因为这是LivecycleOwner对象就不再是组件了,而是ALWAYS_ON;通过该方法添加的观察者,需要手动调用removeObserver()来停止观察者接收回调通知。
·LiveData提供两种改变数据的方法:setValue()和postValue(),setValue在主线程调用,否则抛出异常。postValue既可在主线程也可以在子线程中调用。

特点:
·能够保证数据和UI统一,LiveData是被观察者,当数据有变化时会通知观察者
·减少内存泄漏,当组件处于DESTROYED状态,观察者对象会被清除掉
·当Activity停止时不会引起崩溃,非激活状态不会收到LiveData中数据变化的通知
·不需要额外的手动处理来响应生命周期的变化
·组件和数据相关的内容能实时更新,组件在前台能够实时收到数据改变的通知,组件从后台到前台时,LiveData能够收到最新通知组件
·针对configuration change时,不需要额外处理来保存数据,当configuration change(比如语言、屏幕方向变化)时,组件会被recreate,然而系统并不能保证你的数据能够恢复,当我们采用Livedata保存,数据和组件分离,当组件被recreate,数据还是存在LiveData中,并不会被销毁

LiveData使用

·使用LiveData对象
·继承LiveData对象

使用LiveData:

·创建保存特定数据类型的LiveData实例
·创建Observer对象,作为参数传入LiveData.observe()方法添加观察者
·更新LiveData对象存储的数据

// 在ViewModel中创建LiveData,存储姓名和姓名列表(去掉publish后crsh,必须是publish否则报错)
public class NameViewModel extends ViewModel {
    private MutableLiveData<String> mCurrentName;
    private MutableLiveData<List<String>> mNameListData;

    MutableLiveData<String> getmCurrentName() {
        if (mCurrentName==null){
            mCurrentName = new MutableLiveData<>();
        }
        return mCurrentName;
    }

    MutableLiveData<List<String>> getmNameListData() {
        if (mNameListData == null){
            mNameListData = new MutableLiveData<>();
        }
        return mNameListData;
    }
}
// 创建Observer对象,添加观察者
        mNameViewModel = ViewModelProviders.of(this).get(NameViewModel.class);
        mNameViewModel.getmCurrentName().observe(this, (String name) -> Log.d(TAG, "name:" + name));
        mNameViewModel.getmNameListData().observe(this, (List<String> nameList) -> {
            for (String item : nameList) {
                Log.d(TAG, "list-name:" + item);
            }
        });
// 更新LiveData中的数据
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.tvChangeName:
                Log.d(TAG, "点击-修改名字");
                mNameViewModel.getmCurrentName().setValue("Jane");
                break;
            case R.id.tvChangeList:
                Log.d(TAG, "点击-修改列表");
                List<String> nameList = new ArrayList<>();
                for (int i = 0; i < 10; i++) {
                    nameList.add("Jane<" + i + ">");
                }
                mNameViewModel.getmNameListData().setValue(nameList);
                break;

        }
    }

注意:如果当前activity处于onDestroy/onStop则观察不到数据改变的。如果是在onStop(home键进入后台)中发出的更改LiveData,责观察者观察不到数据改变的,只有当回到前台才会观察到数据的改变(这个逻辑挺好)。

继承LiveData类
定义适合需求的LiveData类,实现资源共享。

Demo地址

上一篇下一篇

猜你喜欢

热点阅读