前言
本文将通过lifecycle代码的阅读理解,来学习aac的一些概念,比如viewmodel,lifecycle,livedata。
代码地址
代码里的activity继承自 AppCompatActivity,而AppCompatActivity继承自FragmentActivity,这个FragmentActivity和我们以前见到的地址可不一样,他是androidx.fragment:fragment这个jar包里面的,对应的gradle库为 androidx.appcompat:appcompat
。
step1 一个简单的计时功能
此处使用了android的一个计时器控件,Chronometer
,这个控件只要调用start
就会开始计时。Chronometer是继承自TextView的
step2 使用viewmodel实现计时功能
step2与step1的唯一区别就是,数据的创建使用了viewmodel。
其实每个activity有个ViewModelStore,viewmodel的创建和获取方式为。每个activity对应一个viewmodel,想想这样有什么好处,我要取数据会非常方便,以前在activity和viewholder之间传数据往往要通过adapter或者设计接口的方式,现在直接通过如下方法去取,简单优雅。
ViewModelProviders.of(this).get(ChronometerViewModel.class)
而且viewmodel是有生命周期的,直接跟activity同步,在activity销毁的时候自动销毁,我们不用考虑内存泄露问题。
ViewModel是存储UI相关数据并不会因为旋转而销毁的类
step3_solution
由于step3是个中间态,我们直接跳过,看step3_solution好了。step3_solution在viewmodel的基础上引入了livedata。看代码,我们在viewmdel里面放了个MutableLiveData,表示这个数据是可变的。这里也不用Chronometer了,直接用TextView。
public class LiveDataTimerViewModel extends ViewModel {
private static final int ONE_SECOND = 1000;
private MutableLiveData<Long> mElapsedTime = new MutableLiveData<>();
private long mInitialTime;
}
这里的关键是通过ViewModel里的liveData更新数据,如何通知页面。具体的说就是如何把当前的时间值传给textview。核心代码如下
//MutableLiveData<Long>
mElapsedTime.postValue(newValue);
//activity
private void subscribe() {
final Observer<Long> elapsedTimeObserver = new Observer<Long>() {
@Override
public void onChanged(@Nullable final Long aLong) {
String newText = ChronoActivity3.this.getResources().getString(
R.string.seconds, aLong);
((TextView) findViewById(R.id.timer_textview)).setText(newText);
Log.d("ChronoActivity3", "Updating timer");
}
};
mLiveDataTimerViewModel.getElapsedTime().observe(this, elapsedTimeObserver);
}
其实很简单就是一个观察者模式,通过postValue来修改LiveData的值,然后在activity里给livedata注册一个观察者。
这里注意一个事情,我们使用了observe,按以前的套路是要在ondestroy的时候,删除观察者的,不然会有内存泄露。这里为甚没有删除的代码呢?这就是aac的第一个好处,liveData是有生命周期的,他会自动在activity destroy的时候删除观察者,代码如下。
//LiveData
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
step4 和step4_solution
这里主要介绍了,lifecycle。
在step4里面,我们需要在onresume的时候addLocationListener
,在onpause的时候removeLocationListener
,这种操作非常常见,在页面可见的时候做一些事情。
用了lifecycle,我们就不用写这么ugly的代码了,可以使用注解OnLifecycleEvent
优雅实现这种需求。核心代码如下 lifecycleOwner可以是activity或fragment
//new
lifecycleOwner.getLifecycle().addObserver(this);
//
@OnLifecycleEvent(Lifecycle.Event.ON_RESUME)
void addLocationListener() {...}
@OnLifecycleEvent(Lifecycle.Event.ON_PAUSE)
void removeLocationListener() {}
step6 和step6_solution
这里主要介绍一种SavedState的ViewModel,实现方式使用SavedStateVMFactory来创建ViewModel,其实和onSaveInstance里面放代码是类似 的,以后再详细分析
ref
https://www.jianshu.com/p/e8955f525f4c