Android ViewModel和LiveData源码分析

ViewModel的创建方式

  1. 通过by viewModels创建(懒加载的方式)
    implementation 'androidx.activity:activity-ktx:1.1.0'//by viewModels
    implementation 'androidx.fragment:fragment-ktx:1.2.5'//by viewModels
    val viewModel: MainViewModel by viewModels { MainViewModelProvider() }
@Suppress("UNCHECKED_CAST")
class MainViewModelProvider : ViewModelProvider.Factory {
    override fun <T : ViewModel?> create(modelClass: Class<T>): T {
        return MainViewModel() as T
    }
}
  1. 直接创建
val viewModel = ViewModelProvider(this).get(MainViewModel::class.java)
  1. Fragment中共享Activity(或者上级Fragment)的ViewModel
val viewModel = ViewModelProvider(requireActivity()).get(LoginViewModel::class.java)

val viewModel = ViewModelProvider(requireParentFragment()).get(LoginViewModel::class.java)

ViewModel源码

  • ViewModelStoreOwner
    实现该接口的有ComponentActivity和Fragment,主要是获取ViewModelStore
public interface ViewModelStoreOwner {
    /**
     * Returns owned {@link ViewModelStore}
     *
     * @return a {@code ViewModelStore}
     */
    @NonNull
    ViewModelStore getViewModelStore();
}

  • ViewModelStore(数据共享原理)
    ViewModelStore存储在ComponentActivity和Fragment中。
    ViewModelStore中根据ViewModel的className存储了ViewModel,我们可以在子Fragment中传入父容器的ViewModelStoreOwner来得到ViewModelStore,然后从ViewModelStore中获取相应的ViewModel来实现ViewModel的共享。
public class ViewModelStore {

    private final HashMap<String, ViewModel> mMap = new HashMap<>();

    final void put(String key, ViewModel viewModel) {
        ViewModel oldViewModel = mMap.put(key, viewModel);
        if (oldViewModel != null) {
            oldViewModel.onCleared();
        }
    }

    final ViewModel get(String key) {
        return mMap.get(key);
    }
}

  • ViewModel在屏幕旋转后不会销毁原理
    主要是因为在ComponentActivity中,当ViewModelStore为空时,会得到上次保存的ViewModelStore。
    public ViewModelStore getViewModelStore() {
        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;
    }

LiveData的优势

  • 例如:
    获取首页的列表,首次加载和加载更多时,数据是变化的,此时使用livedata中存储每次请求的结果,在activity中统一进行观测即可。如果是第一页,则setData否则addData。在列表刷新和加载更多时,只需要一行调用ViewModel.refreshData或ViewModel.loadMoreData方法即可,不需做其他逻辑操作,都交给ViewModel处理
  • 优势:
    简洁逻辑清晰。
    对同一类型的数据集中处理。
    关联持有者的生命周期,防止内存泄漏。

LiveData源码分析

  • observe观测点
    @MainThread
    //owner生命周期的持有者,observer观察者(外部传入已实现的对象)
    public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
    	//必须在主线程
        assertMainThread("observe");
        //观察持有者的生命周期,持有者生命周期销毁,返回
        if (owner.getLifecycle().getCurrentState() == DESTROYED) {
            // ignore
            return;
        }
        //装饰器模式,传入owner和observer
        LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
        //mObservers是一个map,将装饰器缓存一份
        ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
        //如果map已经插入过了,并且持有者不同
        if (existing != null && !existing.isAttachedTo(owner)) {
            throw new IllegalArgumentException("Cannot add the same observer"
                    + " with different lifecycles");
        }
        //map已经插入过了
        if (existing != null) {
            return;
        }
        //持有者和装饰器关联起来,订阅
        owner.getLifecycle().addObserver(wrapper);
    }
  • LifecycleBoundObserver 装饰器
    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(@NonNull LifecycleOwner source,
                @NonNull Lifecycle.Event event) {
            if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
            	//Activity销毁时,移除观察者
                removeObserver(mObserver);
                return;
            }
            activeStateChanged(shouldBeActive());
        }

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

        @Override
        void detachObserver() {
            mOwner.getLifecycle().removeObserver(this);
        }
    }
  • setValue
    @MainThread
    protected void setValue(T value) {
        assertMainThread("setValue");
        mVersion++;
        mData = value;
        dispatchingValue(null);
    }
  • 分发数据
    void dispatchingValue(@Nullable ObserverWrapper initiator) {
        if (mDispatchingValue) {
            mDispatchInvalidated = true;
            return;
        }
        mDispatchingValue = true;
        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;
    }
  • 通知观察者
    private void considerNotify(ObserverWrapper observer) {
        //如果持有者是不可见状态
        if (!observer.mActive) {
            return;
        }
        // Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
        //
        // we still first check observer.active to keep it as the entrance for events. So even if
        // the observer moved to an active state, if we've not received that event, we better not
        // notify for a more predictable notification order.
        if (!observer.shouldBeActive()) {
            observer.activeStateChanged(false);
            return;
        }
        if (observer.mLastVersion >= mVersion) {
            return;
        }
        observer.mLastVersion = mVersion;
        //改变值
        observer.mObserver.onChanged((T) mData);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值