Jetpack架构组件主要用到的又三个Lifecycle,liveData,viewModel。
Lifecycle关联Activity生命周期
Lifecycle使用两个枚举来跟踪其关联组件的生命周期状态,这两个枚举分别是Event和State。 State指的是Lifecycle的生命周期所处的状态。 Event代表Lifecycle生命周期对应的事件,这些事件会映射到Activity和Fragment中的回调事件中
public abstract class Lifecycle {
@MainThread
public abstract void addObserver(@NonNull LifecycleObserver observer);
@MainThread
public abstract void removeObserver(@NonNull LifecycleObserver observer);
@MainThread
@NonNull
public abstract State getCurrentState();
@SuppressWarnings("WeakerAccess")
public enum Event {
ON_CREATE,
ON_START,
ON_RESUME,
ON_PAUSE,
ON_STOP,
ON_DESTROY,
ON_ANY
}
@SuppressWarnings("WeakerAccess")
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
}
AppCompatActivity继承自FragmentActivity,FragmentActivity中创建了LifecycleRegistry,它是Lifecycle的实现类。在fragmentActivity的各个生命周期中均调用了LifecycleRegistry的handleLifecycleEvent方法,改变Lifecycle的状态,
final LifecycleRegistry mFragmentLifecycleRegistry = new LifecycleRegistry(this
/**
* Dispatch onStart() to all fragments.
*/
@Override
protected void onStart() {
super.onStart();
mStopped = false;
if (!mCreated) {
mCreated = true;
mFragments.dispatchActivityCreated();
}
mFragments.noteStateNotSaved();
mFragments.execPendingActions();
// NOTE: HC onStart goes here.
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
mFragments.dispatchStart();
}
liveData感知生命周期
LiveData 通过调用observe方法来注册观察者,这里的owner就是注册的时候传入的组件,通过获取组件当前的状态如果为DESTROYED直接return说明DESTROYED状态的组件是不被注册的
在注释2处新建了一个LifecycleBoundObserver包装类,将owner和observer传了进去。 注释3处将observer和LifecycleBoundObserver存储到SafeIterableMap, ObserverWrapper>mObservers中,putIfAbsent方法和put方法有区别,如果传入key对应的value已经存在,就返回存在的value,不进行替换。如果不存在,就添加key和value,返回null。 如果等于null,在注释4处会将LifecycleBoundObserver添加到Lifecycle中完成注册,这样当我们调用LiveData的observe方法时,实际上是LiveData内部完成了Lifecycle的观察者的添加,这样LiveData自然也就有了观察组件生命周期变化的能力。LiveData并不是通知所有观察者,它只会通知处于Active状态的观察者,如果一个观察者处于DESTROYED状态,它将不会收到通知
LifecycleBoundObserver继承了ObserverWrapper类,重写了shouldBeActive方法,用于判断当前传入的组件的状态是否是Active的,Active状态包括STARTED和RESUMED状态。 LifecycleBoundObserver实现了GenericLifecycleObserver接口,当组件状态发生变化时,会调用onStateChanged方法,当组件处于DESTROYED状态时,会调用removeObserver方法,来移除observer。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
//如果被观察者的当前的状态是DESTROYED,就return
if (owner.getLifecycle().getCurrentState() == DESTROYED) {//1
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);//2
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);//3
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
owner.getLifecycle().addObserver(wrapper);//4
}
当调用MutableLiveData的observe方法后,还需要通过postValue/setValue方法来更新数据。setValue方法是运行在主线程中的,postValue实际上就是切到主线程中调用setValue方法
viewModel使用
创建一个MutableLiveData,并通过MutableLiveData的postValue方法来更新数据,实现
final MutableLiveData<Boolean> data = new MutableLiveData<>();
RequestManager.getInstance().addFavorites(request).
subscribe(new HttpResultCallBack<ResponseData<String>>() {
@Override
public void onSuccess(ResponseData<String> bean) {
data.postValue(bean.isSuccessful());
}
@Override
public void onError(ResponseData<String> result, int code, String msg) {
ToastUtils.showShort(msg);
data.postValue(false);
}
});
来看看我们是如何初始化viewModel的
根据key值从ViewModelStore中获取viewModel如果ViewModel能转换为modelClass类的对象,直接返回该ViewModel。否则会通过Factory创建一个ViewModel,并将其存储到ViewModelStore中。这里的Factory指的是AndroidViewModelFactory,它在ViewModelProvider创建时作为参数传进来。
/**
* 初始化ViewModel
*/
private void initViewModel() {
Class<VM> viewModelClass = ClassUtil.getViewModel(this);
if (viewModelClass != null) {
this.viewModel = ViewModelProviders.of(this).get(viewModelClass);
}
}
@NonNull
@MainThread
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
ViewModel viewModel = mViewModelStore.get(key);
if (modelClass.isInstance(viewModel)) {
if (mFactory instanceof OnRequeryFactory) {
((OnRequeryFactory) mFactory).onRequery(viewModel);
}
return (T) viewModel;
} else {
//noinspection StatementWithEmptyBody
if (viewModel != null) {
// TODO: log a warning.
}
}
if (mFactory instanceof KeyedFactory) {
viewModel = ((KeyedFactory) (mFactory)).create(key, modelClass);
} else {
viewModel = (mFactory).create(modelClass);
}
mViewModelStore.put(key, viewModel);
return (T) viewModel;
}
根据viewModel单一实例的特性以及生命周期跟随application,viewModel的另外一个功能是可以用于数据共享。具体见如下demo
public class FabricDetailsModel extends AndroidViewModel {
private MutableLiveData<FabricDetailsBean> testData = new MutableLiveData<>();
public MutableLiveData<FabricDetailsBean> getFabricDetails(FabricDetailsRequest request){
if(testData ==null){
testData = new MutableLiveData<>();
RequestManager.getInstance().getFabricDetails(request).
subscribe(new HttpResultDataCallBack<FabricDetailsBean>() {
@Override
public void onSuccess(FabricDetailsBean bean) {
testData.postValue(bean);
}
@Override
public void onError(FabricDetailsBean bean, int code, String msg) {
ToastUtils.showShort(msg);
testData.postValue(null);
}
});
}
return testData;
}
public MutableLiveData<FabricDetailsBean> getTestData() {
return testData;
}
public void setTestData(MutableLiveData<FabricDetailsBean> testData) {
this.testData = testData;
}
}
public class TestActivity extends BaseActivity <AndroidViewModel, FabricDetailsActivityBinding>{
@Override
public int getContentView() {
return R.layout.fabric_details_activity;
}
@Override
protected void initView() {
FabricDetailsModel myViewMode = new ViewModelProvider(this).get(FabricDetailsModel.class);
myViewMode.getTestData().observe(this, bean -> {
});
}
@Override
public void initData() {
}
}