jetpack 学习 ViewModel

1.介绍
ViewModel,意为 视图模型,即 为界面准备数据的模型。就是ViewModel为UI层提供数据。
官方文档定义如下:

  • ViewModel 以注重生命周期的方式存储和管理界面相关的数据。(作用)
  • ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。(特点)
    作用:
  • 因配置更改导致页面重建后可以保存页面数据
  • ViewModel不持有View 在数据变更的时候通知View数据变更
  • ViewModel的生命周期与Activity的生命周期绑定,可以有效的防止内存泄露
    2.ViewModel使用
  • 继承ViewModel自定义MyViewModel
  • 在MyViewModel中编写获取UI数据的逻辑
  • 使用LiveData将获取到的UI数据抛出
  • 在Activity/Fragment中使用ViewModelProvider获取MyViewModel实例
  • 观察MyViewModel中的LiveData数据,进行对应的UI更新。
public class UserViewModel extends ViewModel {

    private MutableLiveData userLiveData ;
    private MutableLiveData loadingLiveData;

    public UserViewModel() {
        userLiveData = new MutableLiveData<>();
        loadingLiveData = new MutableLiveData<>();
    }

    //获取用户信息,假装网络请求 2s后 返回用户信息
    public void getUserInfo() {

        loadingLiveData.setValue(true);

        new AsyncTask() {
            @Override
            protected void onPostExecute(String s) {
                loadingLiveData.setValue(false);
                userLiveData.setValue(s);//抛出用户信息
            }
            @Override
            protected String doInBackground(Void... voids) {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                String userName = "......";
                return userName;
            }
        }.execute();
    }

    public LiveData getUserLiveData() {
        return userLiveData;
    }
    public LiveData getLoadingLiveData() {
        return loadingLiveData;
    }
}

UserViewModel继承ViewModel,然后逻辑很简单:假装网络请求 2s后 返回用户信息,其中userLiveData用于抛出用户信息,loadingLiveData用于控制进度条显示。
在看UI层

public class UserActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        Log.i(TAG, "onCreate: ");

        TextView tvUserName = findViewById(R.id.textView);
        ProgressBar pbLoading = findViewById(R.id.pb_loading);
    //获取ViewModel实例
        ViewModelProvider viewModelProvider = new ViewModelProvider(this);
        UserViewModel userViewModel = viewModelProvider.get(UserViewModel.class);
        //观察 用户信息
        userViewModel.getUserLiveData().observe(this, new Observer() {
            @Override
            public void onChanged(String s) {
                // update ui.
                tvUserName.setText(s);
            }
        });

        userViewModel.getLoadingLiveData().observe(this, new Observer() {
            @Override
            public void onChanged(Boolean aBoolean) {
                pbLoading.setVisibility(aBoolean?View.VISIBLE:View.GONE);
            }
        });
        //点击按钮获取用户信息
        findViewById(R.id.button).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                userViewModel.getUserInfo();
            }
        });
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, "onStop: ");
    }
    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy: ");
    }
}

页面有个按钮用于点击获取用户信息,有个TextView展示用户信息。 在onCreate()中先 创建ViewModelProvider实例,传入的参数是ViewModelStoreOwner,Activity和Fragment都是其实现。然后通过ViewModelProvider的get方法 获取ViewModel实例,然后就是 观察ViewModel中的LiveData。

源码分析
我们主要分析一个部分 ViewModel是如何存储数据的,以为什么页面的重建不会导致数据丢失。

public abstract class ViewModel {
    ...
    private volatile boolean mCleared = false;
    //在ViewModel将被清除时调用
    //当ViewModel观察了一些数据,可以在这里做解注册 防止内存泄漏
    @SuppressWarnings("WeakerAccess")
    protected void onCleared() {
    }
    @MainThread
    final void clear() {
        mCleared = true;
        ...
        onCleared();
    }
...
}

ViewModel类 是抽象类,内部没有啥逻辑,有个clear()方法会在ViewModel将被清除时调用。

然后ViewModel实例的获取是通过ViewModelProvider类,见名知意,即ViewModel提供者,来看下它的构造方法:

你可能感兴趣的:(jetpack 学习 ViewModel)