前言: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)
);
}
}