MVVM的生命周期管理

554 阅读2分钟

前言:mvvm的一个重要特点就是viewModel 和 view的解耦,他们之间通过databinding&observerableField&ObserverableArrayList & livedata(SingleLivaData) 进行通信. 这样的话,我们就要解决一个问题:

view层(Activity/Fragment)是有生命周期的如何被viewmodel感知?

分为三步:

1.首先IBaseViewModel extends LifecycleObserver, 在BaseViewModel中实现

2.BaseActivity extends RxAppCompatActivity 提供getLifecycle()方法

3.BaseMvvmActivity extends BaseActivity #initViewDataBinding()} 中将生命周期传递给viewModel : 

getLifecycle().addObserver(mViewModel);

这样viewModel中就感知了(Activity/Fragment)的生命周期

/**
 * Description: <IBaseViewModel><br> Author:      mxdl<br> Date:        2019/06/30<br> Version:     V1.0.0<br> Update:     <br>
 * <p>
 * {@link BaseMvvmActivity#initViewDataBinding()} 中
 *  getLifecycle().addObserver(mViewModel); 将生命周期传递给viewModel
 */
public interface IBaseViewModel extends LifecycleObserver {

  @OnLifecycleEvent(Lifecycle.Event.ON_ANY)
  void onAny(LifecycleOwner owner, Lifecycle.Event event);

  @OnLifecycleEvent(Lifecycle.Event.ON_CREATE)
  void onCreate(@NotNull LifecycleOwner owner);

  @OnLifecycleEvent(Lifecycle.Event.ON_DESTROY)
  void onDestroy(@NotNull LifecycleOwner owner);

  @OnLifecycleEvent(Lifecycle.Event.ON_START)
  void onStart(@NotNull LifecycleOwner owner);

  @OnLifecycleEvent(Lifecycle.Event.ON_STOP)
  void onStop(@NotNull LifecycleOwner owner);

  @OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
  void onResume(@NotNull LifecycleOwner owner);

  @OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
  void onPause(@NotNull LifecycleOwner owner);
}

如:通过生命周期控制实现lazyInitData

在BaseViewModel 的oncreate 中初始化 lifecycleOwnerWeakReference,通过 EventBus通知BaseActivity进行 initData

  /**
   * 为了适配AutoDispose需要在initdata时viewmodel中的lifecycleOwner不为null
   * <p>
   * 参考{@link com.lib.common.mvvm.BaseActivity#lazyInitData(LifecycleOwner)}
   *
   * @param owner
   */
  @Override
  public void onCreate(@NotNull LifecycleOwner owner) {
    this.lifecycleOwnerWeakReference = new WeakReference<>(owner);
    EventBus.getDefault().post(owner);
  }

  /**
   * lifecycleOwner 实际是viewModel所在的activity/fragment对象,解除引用防止内存泄漏
   */
  @Override
  public void onDestroy(@NotNull LifecycleOwner owner) {
    this.mModel = null;
  }



 /**
   * 为了适配AutoDispose需要在initdata时viewmodel中的lifecycleOwner不为null
   * <p>
   * 参考{@link com.lib.common.mvvm.viewmodel.BaseViewModel#onCreate(LifecycleOwner)}
   *
   * @param owner
   */
  @Subscribe(threadMode = ThreadMode.MAIN)
  public void lazyInitData(LifecycleOwner owner) {
    //如果是该fragment发送的事件则执行initdata
    if (owner == this) {
      initData();
    }
  }

另外,还有一个问题:  viewmodel 调用model数据接口获取数据的时候,是通过Rxjava+Retrofit的形式, 通过Observable. subscribe 获取数据, 也就是观察者模式,

viewmodel 对model 数据的订阅又是怎么和activity的生命周期绑定的呢?

我们看到在MainModel 中通过RxAdapter.rxSchedulerHelper(autoBindLifecycler)进行了生命周期自动绑定, IAutoBindLifecycler 是从viewmodel中传过来的 this

MainVModel .java

  public void checkUpdate(IAutoBindLifecycler autoBindLifecycler, String versionName, String versionCode, String posId,
      String payCompany, DefaultMvvmObserver<VersionEntity> observer) {
    ApiServiceHelper.getUserApiService()
        .checkUpdate(versionName, versionCode, posId, payCompany)
        .to(RxAdapter.rxSchedulerHelper(autoBindLifecycler)) //1
        .subscribe(observer);
  }

  public static <T> ObservableConverter<T, ObservableSubscribeProxy<T>> rxSchedulerHelper(
      final IAutoBindLifecycler autoBindLifecycle) {
    return observable -> observable.subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .to(autoBindLifecycle.autoBindLifecycle());//2
  }


public interface IAutoBindLifecycler {

  public <T> AutoDisposeConverter<T> autoBindLifecycle();
}

MainViewModel.java

 public void checkUpdate(String versionName, String versionCode, String posId, String payCompany) {

    mModel.checkUpdate(this, versionName, versionCode, posId, payCompany,
        new DefaultMvvmObserver<VersionEntity>(this, DefaultMvvmObserver.LOADING_TYPE_TRANS) {
          @Override
          public void onSuccess(VersionEntity response) {

          }

        });
  }

BaseViewModel实现了IAutoBindLifecycler autoBindLifecycle()

注意:注释3处lifecycleOwnerWeakReference 上面已经讲过

BaseViewModel.java

public class BaseViewModel<M extends BaseModel> extends AndroidViewModel implements IBaseViewModel, Consumer<Disposable>,
    IAutoBindLifecycler {

...
  @Override
  public <T> AutoDisposeConverter<T> autoBindLifecycle() {
    if (lifecycleOwnerWeakReference == null || lifecycleOwnerWeakReference.get() == null) {
      throw new NullPointerException("lifecycleOwner == null");
    }
    return RxLifecycleUtils.autoBindLifecycle(lifecycleOwnerWeakReference.get());//3
  }
...
}

最终通过AutoDispose实现绑定: AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner) 

public class RxLifecycleUtils {

  private RxLifecycleUtils() {
    throw new IllegalStateException("Can't instance the RxLifecycleUtils");
  }

  public static <T> AutoDisposeConverter<T> autoBindLifecycle(LifecycleOwner lifecycleOwner) {
    return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycleOwner)
    );
  }

}