美文网首页
LiveData - ViewModel

LiveData - ViewModel

作者: leap_ | 来源:发表于2021-03-15 19:58 被阅读0次

LiveData:

  • 具有生命周期感知能力
  • LiveData 遵循观察者模式。当底层数据发生变化时,LiveData 会通知 Observer
        myViewModel.liveData.observe(this, new Observer() {
            @Override
            public void onChanged(Object o) {
                textView.setText(o.toString());
            }
        });
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                myViewModel.liveData.setValue(System.currentTimeMillis());
            }
        });

当livedata数据发生变化时,会通知所有的observer的onChanged();

LiveData.observe() 添加LiveData的观察者:

    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
        
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        // 分析1
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);

        // 分享2
        owner.getLifecycle().addObserver(wrapper);
    }
  • 添加Observer到LiveData的mObservers中,当数据变化时,遍历这些观察者
  • 添加给页面的观察者集合,当页面Destory的时候,回收LiveData
    class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
        @NonNull
        final LifecycleOwner mOwner;

        LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
            super(observer);
            mOwner = owner;
        }

        @Override
        boolean shouldBeActive() {
            return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
        }

        @Override
        public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }

        @Override
        boolean isAttachedTo(LifecycleOwner owner) {
            return mOwner == owner;
        }

        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }

LiveData.setValue():

    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }


    void dispatchingValue(@Nullable ObserverWrapper initiator) {

        do {
            mDispatchInvalidated = false;
            if (initiator != null) {
                considerNotify(initiator);
                initiator = null;
            } else {
                for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
                        mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
                    considerNotify(iterator.next().getValue());
                    if (mDispatchInvalidated) {
                        break;
                    }
                }
            }
        } while (mDispatchInvalidated);
        mDispatchingValue = false;
    }
  • 当数据发生改变的时候,通知LiveData的所有观察者

ViewMdel:

  • 以注重生命周期的方式存储和管理界面相关的数据
  • 当页面因为configuration change发生改变的时候,不会被销毁
  • only manage the data for the UI,never hold reference of Act/Fag
Acticity与Fragment通信
public class MyFragment extends Fragment {
     public void onStart() {

         UserModel userModel = ViewModelProviders.of(getActivity()).get(UserModel.class);
     }
 }

这里拿到的ViewModel实例,其实是和Activity中创建的是一个实例

Activity有一个成员变量:

    private ViewModelStore mViewModelStore;

在发生configration的时候,系统会回调:

    public final Object onRetainNonConfigurationInstance() {
        Object custom = onRetainCustomNonConfigurationInstance();

        ViewModelStore viewModelStore = mViewModelStore;
        if (viewModelStore == null) {
            // No one called getViewModelStore(), so see if there was an existing
            // ViewModelStore from our last NonConfigurationInstance
            NonConfigurationInstances nc =
                    (NonConfigurationInstances) getLastNonConfigurationInstance();
            if (nc != null) {
                viewModelStore = nc.viewModelStore;
            }
        }

        if (viewModelStore == null && custom == null) {
            return null;
        }

        NonConfigurationInstances nci = new NonConfigurationInstances();
        nci.custom = custom;
        nci.viewModelStore = viewModelStore;
        return nci;
    }

当activity横竖切换销毁时,在此对mViewModelStore变量进行保存;

获取mViewModelStore
    // ComponentActivity
    public ViewModelStore getViewModelStore() {
        if (getApplication() == null) {
            throw new IllegalStateException("Your activity is not yet attached to the "
                    + "Application instance. You can't request ViewModel before onCreate call.");
        }
        if (mViewModelStore == null) {
            NonConfigurationInstances nc =
                    (NonConfigurationInstances) getLastNonConfigurationInstance();
            if (nc != null) {
                // Restore the ViewModelStore from NonConfigurationInstances
                mViewModelStore = nc.viewModelStore;
            }
            if (mViewModelStore == null) {
                mViewModelStore = new ViewModelStore();
            }
        }
        return mViewModelStore;
    }

    //  Activity
    public Object getLastNonConfigurationInstance() {
        return mLastNonConfigurationInstances != null
                ? mLastNonConfigurationInstances.activity : null;
    }

通过getLastNonConfigurationInstance ()获取nc,然后mViewModelStore就存放在nc中;

ViewModel中不能持有Android FrameWork的类

  • 单纯的数据持有类,不能跟安卓sdk有任何关联
  • 在viewModel中持有view是一件非常危险的事情,viewModel可以借助liveData的观察者模式来和view进行互动
  • Instead of pushing data to the UI, let the UI observe changes to it.

相关文章

网友评论

      本文标题:LiveData - ViewModel

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