美文网首页
jetpack 学习 ViewModel

jetpack 学习 ViewModel

作者: 刘景昌 | 来源:发表于2021-04-14 15:38 被阅读0次

    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<String> userLiveData ;
        private MutableLiveData<Boolean> loadingLiveData;
    
        public UserViewModel() {
            userLiveData = new MutableLiveData<>();
            loadingLiveData = new MutableLiveData<>();
        }
    
        //获取用户信息,假装网络请求 2s后 返回用户信息
        public void getUserInfo() {
    
            loadingLiveData.setValue(true);
    
            new AsyncTask<Void, Void, String>() {
                @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<String> getUserLiveData() {
            return userLiveData;
        }
        public LiveData<Boolean> 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<String>() {
                @Override
                public void onChanged(String s) {
                    // update ui.
                    tvUserName.setText(s);
                }
            });
    
            userViewModel.getLoadingLiveData().observe(this, new Observer<Boolean>() {
                @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

          本文链接:https://www.haomeiwen.com/subject/hvbrcltx.html