ViewModel的使用和原理

首先我们要知道ViewModel是什么?怎么用?内部怎么实现的?好处是什么?

ViewModel 是一种用来存储和管理UI相关数据的类。但不同的是,它支持在系统配置发生改变的时候自动对数据进行保存。谷歌推荐我们配合 LiveData使用,当然你也可以往里面存任何数据或者其他参数等。

为什么我们要使用ViewModel?因为对于一些简单的数据,我们可以通过在Activity的 onSaveInstanceState()方法中存储,然后在onCreate()中进行恢复,但是这种方式只适合存储少量的数据,并且是能被序列化和反序列化的数据。而对那些大量的数据则不适用,比如一个 User 或者 Bitmap 的 List。此外,它也使得 View 的数据持有者和 UI controller 逻辑更加分离,便于解耦和测试。

Activity配置更改重建时(比如屏幕旋转)保留数据

UI组件(Activity与Fragment、Fragment与Fragment)间实现数据共享。

一、ViewModel的使用

1.引入ViewModel

def lifecycle_version = "2.0.0"

// ViewModel and LiveData

implementation "androidx.lifecycle:lifecycle-extensions:$lifecycle_version"

2. 简单使用起来

public class UserModel extends ViewModel {

    public final MutableLiveData mUserLiveData = new MutableLiveData<>();

    public UserModel() {

        //模拟从网络加载用户信息

        mUserLiveData.postValue(new User(1, "name1"));

    }

    //模拟 进行一些数据操作

    public void doSomething() {

        User user = mUserLiveData.getValue();

        if (user != null) {

            user.age = 1;

            mUserLiveData.setValue(user);

        }

    }

}

3.这时候在Activity中就可以使用ViewModel了. 其实就是一句代码简单实例化,然后就可以使用ViewModel了.

//构建ViewModel实例

        final UserModel userModel = ViewModelProviders.of(this).get(UserModel.class);

        //让TextView观察ViewModel中数据的变化,并实时展示

        userModel.mUserLiveData.observe(this, new Observer() {

            @Override

            public void onChanged(User user) {

                mContentTv.setText(user.toString());

            }

        });

        findViewById(R.id.btn_test).setOnClickListener(new View.OnClickListener() {

            @Override

            public void onClick(View view) {

                //点击按钮  更新User数据  观察TextView变化

                userModel.doSomething();

            }

        });

这个时候,我们点击一下按钮(user中的age变为15),我们可以旋转手机屏幕(这个时候其实Activity是重新创建了,也就是onCreate()方法被再次调用,但是ViewModel其实是没有重新创建的,还是之前那个ViewModel),但是当我们旋转之后,发现TextView上显示的age居然还是15,,,,这就是ViewModel的魔性所在.ViewModel也常用于Activity和Fragment之间进行逻辑传值处理等。提下ViewModel的生命周期了,它只有在Activity销毁之后,它才会自动销毁(所以别让ViewModel持有Activity引用啊,会内存泄露的). 下面引用一下谷歌官方的图片,将ViewModel的生命周期展示的淋漓尽致.


二、ViewModel源码解析

UserModel userModel = ViewModelProviders.of(this).get(UserModel.class);

首先看下ViewModelProviders.of(this)

这里通过factory单例工厂获取factory,再看.get(MyViewModel.class)逻辑:


Java中获取类名主要有三个方法供我们使用:getName(), getCanonicalName() 和getSimpleName(),通过类名的键值对进行缓存

这里进行ViewModel的获取,如果ViewModelStore中有缓存直接获取缓存,如果没有,就新创建一个,然后再存储起来返回。这里的创建是通过AndroidViewModelFactory,通过反射创建ViewModel实体类

我们这里重点关注下ViewModelStore这个类,


在ComponentActivity中,onRetainNonConfigurationInstance()也具有相同的目的来处理类似的请求,其主要是由于旋转设备而更改显示模式,进而触发这个方法的调用。

这里就是通过从ViewModelStrore中的一样的key获取同一个VIewModel来进行数据的操作的,屏幕旋转或者通过Fragment传值getActivity()来进行使用

你可能感兴趣的:(ViewModel的使用和原理)