Android官方组件之ViewModel结合LiveData

作者: 燊在锦官城 | 来源:发表于2020-04-02 17:38 被阅读0次

    LiveData的优点

    • 不用手动控制生命周期,当数据变化它只会给前台活动的activity回调。
    • 不用担心内存泄露。
    • 如果一个观察者处于 Paused 或 Destroyed。 状态,它将不会受到通知,一旦观察者重新恢复 Resumed 状态,它将会收到 LiveData 的最新数据。

    ViewModel的优点

    为Activity、Fragment存储数据,直到完全销毁,不会发生试图去刷新那些不存在的了View而出现空指针异常。

    引入

        def lifecycle_version = "1.1.1"
        // ViewModel and LiveData
        implementation "android.arch.lifecycle:extensions:$lifecycle_version"
        // alternatively - just ViewModel
        implementation "android.arch.lifecycle:viewmodel:$lifecycle_version"
        // alternatively - just LiveData
        implementation "android.arch.lifecycle:livedata:$lifecycle_version"
    

    创建MutableLiveData

    MutableLiveData是LiveData的子类,添加了公共方法setValue和postValue

    public class UserViewModel extends ViewModel {
        public MutableLiveData<String> user = new MutableLiveData<>();
    }
    

    在Activity或者Fragment绑定

    public class DemoActivity extends Activity {
        private UserViewModel userViewModel;
        private Button mBtn;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_demo);
            ...
            userViewModel = ViewModelProviders.of(this).get(DemoViewModel.class);
            userViewModel.getMyString().observe(this, new Observer<String>() { //注册观察者
                @Override
                public void onChanged(String s) {
                    Log.e(TAG, "onChanged: 监听值有变化="+s);
                }
            });
    
            mBtn.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 改变值
                    mDemoViewModel.setMyString("测试"); 
                }
            }
        }
    }
    

    API

    1. postValue()

    在子线程刷新数据。

    2. setValue()

    只能在主线程里调用。

    3. getValue()

    返回当前值。

    4. observe

    绑定观察者, 会给此activity或者Fragment在前台时回调数据(onStarted或者onResumed状态)。

    5. removeObserver(@NonNull final Observer<? super T> observer)

    移除指定观察者。

    6. removeObservers(@NonNull final LifecycleOwner owner)

    移除当前Activity或者Fragment的全部观察者。

    mMainViewModel.getContent().removeObservers(this);
    

    7. hasActiveObservers()

    如果此LiveData具有活动(Activity或者Fragment在前台,当前屏幕显示)的观察者,则返回true。其实如果这个数据的观察者在最前台就返回true,否则false。

    8. hasObservers()

    如果此LiveData具有观察者,则返回true。

    9. observeForever(@NonNull Observer<? super T> observer)

    设置永远观察者,永远不会被自动删除。您需要手动调用removeObserver(Observer)以停止观察此LiveData,设置后此LiveData,一直处于活动状态,不管是否在前台哪里都会获得回调。

    10. onActive()

    在LiveData中,onActive方法回调表明当前Activity处于激活状态,也就是Activity处于生命周期的活动状态中(onStart,onResume),可以简单认为当前的Activity处于前台。

    11. onInactive()

    LiveData的onInactive处理涉及onActive剩下的生命周期,可以简单理解onInactive是Android的Activity/Fragment处于未激活(后台,比如当前Activity处于生命周期的onStop,onPause)。

    12. ViewModelProvider.of(@NonNull Fragment fragment, @Nullable Factory factory)

    向ViewModel传参。

    public class TestViewModel extends ViewModel {
    
        private final String mKey;
        private MutableLiveData<String> mNameEvent = new MutableLiveData<>();
    
        public MutableLiveData<String> getNameEvent() {
            return mNameEvent;
        }
    
        public TestViewModel(String key) {
            mKey = key;
        }
    
        public static class Factory implements ViewModelProvider.Factory {
            private String mKey;
    
            public Factory(String key) {
                mKey = key;
            }
    
            @Override
            public <T extends ViewModel> T create(Class<T> modelClass) {
                return (T) new TestViewModel(mKey);
            }
        }
    
        public String getKey() {
            return mKey;
        }
    }
    
    ViewModelProviders.of(this, new TestViewModel.Factory(mkey)).get(TestViewModel.class)
    

    使用场景

    • 当 config 导致 activity 重新创建的时候,不需要手动取处理数据的储存和恢复。它已经帮我们封装好了。
    • 多个fragment同步数据。
    • 监听网络变化处理数据。
    • 在Activity处于不可见比如用户按Home键不可见时候,此时可能不希望再做处理,那么就可以在LiveData的onInactive做一个逻辑处理,改变任务的状态,如果当前Activity又被用户调回前台,那么可以在LiveData的onActive重新恢复任务的运行。

    建议

    • ViewModel(和presenter)不要和Android Framework里的任何类发生关系。
    • ViewModel 不应持有 View、Lifecycle、或其他可能持有 Activity 的 Context 的类的引用。
    • 其他类不应持有 ViewModel 的引用。在 Activity 或 Fragment 销毁后,其它任何比 Activity 或 Fragment 生命周期长的类都不应再持有 ViewModel 的引用,否则会影响 ViewModel 被 GC 回收,从而泄露 ViewModel。
    • 用一个包装类或者另一个LiveData来发出数据的状态,比如可以在ViewModel放出一个LiveData<MyDataState>. 例如, MyDataState 包含数据正在加载中,已经成功加载或加载失败了3种信息。
    • 要有效存取和恢复UI状态,组合使用persistence, onSaveInstanceState()和 ViewModels。

    参考

    相关文章

      网友评论

        本文标题:Android官方组件之ViewModel结合LiveData

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