ViewModel 概述

ViewModel 被设计为对生命周期敏感的方式存储和管理UI相关数据。ViewModel 模型类允许数据在配置更改(如屏幕旋转)中生存。在上面两篇文章中其实已经广泛的使用了ViewModel。这里我们在主要了解一下。

如果系统破坏或重新创建UI控制器,则在其中存储的任何与UI相关的临时数据都会丢失。例如,您的应用程序可以保存用户在其中一个activity中的列表。当为配置更改重新创建activity时,新activity必须重新获取用户列表。对于简单数据,该活动可以使用onSaveInstanceState()方法并从onCreate()中的bundle恢复其数据,但是这种方法仅适用于可以序列化然后反序列化的少量数据,而不适用于潜在的大量数据,如用户列表或位图。

另一个问题是,UI组件会频繁的调用异步回调,这些回调可能会非常耗时。这就需要UI组件管理这些调用,并且在UI组件销毁时清除这些调用。这会花费很多的维护成本,而且当UI由于configuration change重新创建时,又需要重新调用,这明显是一种资源浪费(比如网络请求)。

最后,还有一个问题就是UI组件需要对用户的操作作出响应,并且处理和操作系统的通信。这样把代码放在UI组件中会使这部分代码变得臃肿,而且对测试也不太友好。

如何实现一个ViewModel

ViewModel
就是用于解决上述问题的。ViewModel用于为UI组件提供数据,并且能够在旋转屏幕等Configuration Change发生时,仍能保持里面的数据。当UI组件恢复时,可以立刻向UI提供数据。一起看下代码:

public class MyViewModel extends ViewModel {
    private MutableLiveData> users;
    public LiveData> getUsers() {
        if (users == null) {
            users = new MutableLiveData>();
            loadUsers();
        }
        return users;
    }

    private void loadUsers() {
        // do async operation to fetch users
    }
}

Activity访问User List数据:

public class MyActivity extends AppCompatActivity {
    public void onCreate(Bundle savedInstanceState) {
        // Create a ViewModel the first time the system calls an activity's onCreate() method.
        // Re-created activities receive the same MyViewModel instance created by the first activity.

        MyViewModel model = ViewModelProviders.of(this).get(MyViewModel.class);
        model.getUsers().observe(this, users -> {
            // update UI
        });
    }
}

当主动销毁了这个Activity呢?这时系统会调用ViewModelonCleared()方法,清除ViewModel中的数据。
这里要特别注意的是,ViewModel绝不能有View的引用、生命周期或任何可以引用activity上下文的类。为什么呢?

因为ViewModel模型对象被设计出来,本身它的生命周期就比任何实例化的View或者activity长。所以如果你的activity已经结束了,而你又在更新数据,会造成内存泄露等问题。如果实在需要系统服务等需要上下文的类,你可以关注下AndroidViewModel

我们看看ViewModel的生命周期

ViewModelProvider获取到ViewModelViewModel才会被划分生命周期。ViewModel一直保留在内存中,直到它的作用域永久消失。
下面的图片是一个activity经历旋转后ViewModel对应得周期。


所以我们一般在onCreate()方法中就获取到ViewModel

你可能感兴趣的:(ViewModel 概述)