Android Jetpack – LiveData【JAVA教程】

!
也想出现在这里? 联系我们
信息

Android Jetpack - LiveData,第1张

LiveData 一般是和 ViewModel 结合起来使用的,比如计数器功能,在单线程模式下确实可以正常工作,但如果在 ViewModel 的内部开启了线程去执行一些耗时逻辑,那么在点击按钮后就我们想立即去获取最新的数据,但是得到的肯定还是之前的旧数据。

**原本我们一直使用的都是在 Activity 中手动的获取 ViewModel 中的数据这种交互方式,但是 ViewModel 却无法将数据的变化主动地通知给 Activity。**那么怎么实现主动通知呢?或许你会说将 Activity 的实例传给 ViewModel,这样 ViewModel 不就能主动通知 Activity 了吗?很可惜,这是错误的。因为 ViewModel 的生命周期是长于 Activity,如果这样做了,那么可能因为 Activity 无法释放而造成内存泄漏。

LiveData 可以轻松地解决这个问题。LiveData 可以包含任何类型的数据,并在数据发生变化的时候通知给观察者。也就是说,我们可以将数据使用 LiveData 来包装,然后在 Activity 中去观察它,就可以将数据变化通知给 Activity。

使用示例:这里和 ViewModel 结合使用

  1. 创建 ViewModel 将里面的数据用 LiveData 包装起来
public class MyViewModel extends ViewModel {

    public MyViewModel(int countReserved) {
        this._counter.setValue(countReserved);
    }
    // LiveData 是不可变的
    // 我们给 _counter 加上 private 修饰符,这样 _counter 外部就不可见了。
    // 然后我们定义不可变的 counter 变量,并让它的 getValue() 方法返回 _counter 中的数据。
    // 这样,当外部调用 counter 变量时,其实获取到的是 _counter 的值,
    // 但是无法给 _counter 设置数据,从而保证了ViewModel 的数据封装性 
    public LiveData<Integer> counter = new LiveData<Integer>() {
        @Override
        public Integer getValue() {
            return _counter.getValue();
        }
    };
    // MutableLiveData 是一种可变的 LiveData
    private MutableLiveData<Integer> _counter = new MutableLiveData<Integer>();

    public void plus() {
        int value = counter.getValue() == null ? 0 : counter.getValue()+1;
        _counter.setValue(value);
    }

    public void clear() {
        _counter.setValue(0);
    }
}

主要有三种读写数据的方法,分别是 getValue()、setValue() 和 postValue() 方法。setValue() 只能在主线程中使用,postValue() 可以用于非主线程中使用。

  1. 通过viewModel.counter 的 observe() 方法来观察数据的变化:
		viewModel1 = new ViewModelProvider(this, new ViewModelProvider.Factory() {
            @NonNull
            @Override
            public <T extends ViewModel> T create(@NonNull Class<T> modelClass) {
                return (T) new com.example.androidjetpack.LiveData.MyViewModel(countReserved);
            }
        }).get(com.example.androidjetpack.LiveData.MyViewModel.class);

        plusButton.setOnClickListener(view -> viewModel1.plus());

        clearButton.setOnClickListener(view -> viewModel1.clear());
        // 当 counter 中包含的数据发生变化时就会回调到这里
        viewModel1.counter.observe(this, new Observer<Integer>() {
            @Override
            public void onChanged(Integer integer) {
                String text = viewModel1.counter.getValue()==null ? \"\" :
                        viewModel1.counter.getValue().toString();
                infoText.setText(text);
            }
        });
© 版权声明
THE END
喜欢就支持一下吧
点赞63 分享
评论 抢沙发

请登录后发表评论

    请登录后查看评论内容