文章目录
前言
LivedData作为Jetpack的一部分,在很多地方可以看到的他的身影,比如Room直接支持LiveData,Android架构规范中也有推荐使用,因此了解整个实现原理,更有助于我们在开发中灵活的使用。
使用LiveData的优势:
1. 确保界面符合数据状态
LiveData 遵循观察者模式。当生命周期状态发生变化时,LiveData 会通知 Observer 对象。您可以整合代码以在这些 Observer 对象中更新界面。观察者可以在每次发生更改时更新界面,而不是在每次应用数据发生更改时更新界面
2.不会发生内存泄漏
观察者会绑定到 Lifecycle 对象,并在其关联的生命周期遭到销毁后进行自我清理。
3.不会因 Activity 停止而导致崩溃
如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。
4.不再需要手动处理生命周期
界面组件只是观察相关数据,不会停止或恢复观察。LiveData
将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化
5.数据始终保持最新状态
如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
6.适当的配置更改
如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。
7.共享资源
您可以使用单一实例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。LiveData 对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData 对象
为了解如何实现以上优势,我们需要自己手写一遍源码,这样所有的疑惑解答
源码实现
一、 实现可观察的数据存储器
可观察的数据存储器是它的基本功能,我们的第一步就是实现它;可观察的数据存储器,顾名思义:第一,可以存储数据;第二:数据发生变化时可以通知观察者。
第一步,定义观察者,当数据发生变化的时候,可通过该观察者进行回调处理。
public interface Observer<T> {
/**
* Called when the data is changed.
* @param t The new data
*/
void onChanged(T t);
}
第二步,定义数据存储类
public class LiveData<T> {
static final Object NOT_SET = new Object();
//数据存储
private volatile Object mData = NOT_SET;
static final int START_VERSION = -1;
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
/**
* 注册观察者
* @param observer 该observer可监听所有的事件,观察者一直处于活跃状态,只要数据发生变化,就能收到事件回调
*/
public void observeForever(Observer<? super T> observer) {
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
//同一个observer存储一次
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if(existing != null){
return;
}
//新注册的观察者,默认设置为active状态,从而能及时接收当前最新数据
wrapper.activeStateChanged(true);
}
//对Observer进行包装处理
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
}
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
}
第三步,改变数据,通知观察者
public void setValue(T value){
mVersion++;
mData = value;
dispatchingValue(null);
}
//对数据进行分发处理
private void dispatchingValue(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;
}
if(!observer.shouldBeActive()){
observer.activeStateChanged(false);
return;
}
//数据源版本区分
if(observer.mLastVersion >= mVersion){
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T)mData);
}
第三步,测试
public static void testLiveData() {
LiveData<String> userName = new LiveData<>();
userName.observeForever(s -> System.out.println("new Observer A rec data:"+s));
userName.setValue("Test");
userName.observeForever(s -> System.out.println("new Observer B rec data:"+s));
userName.observeForever(s -> System.out.println("new Observer C rec data:"+s));
userName.setValue("Test Last");
}
输出结果:
new Observer A rec data:Test
new Observer B rec data:Test
new Observer C rec data:Test
new Observer A rec data:Test Last
new Observer B rec data:Test Last
new Observer C rec data:Test Last
程序运行的结果符合预期标准,使用observeForever注册监听后,我们并没有手动移除相关的监听者,有可能会造成内存泄漏,因此,我们需要合适的时候手动调用removeObserver()方法对Observe进行移除。
二、 感知应用组件的生命变化,并针对相应的事件做相关处理
/**
* 1,对应的observer只有在owner处于active(Lifecycle.State#STARTED或者@link Lifecycle.State#RESUMED)的时候才能接受事件
* 2,如果owner在Lifecycle.State#DESTROYED后会,observer会被自动移除
* 3,如果数据在owner不是活跃状态下改变,observer不会接受任何更新,当处于活跃状态后,可接受最新的数据
* 4,同一个observer只能对应对应的owner
*
* @param owner
* @param observer
*/
public void observe(LifecycleOwner owner, Observer<? super T> observer) {
if (owner.getLifecycle().getCurrentState() == Lifecycle.State.DESTROYED) {
return;
}
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner,observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
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);
}
//这里的使用的是LifecycleBoundObserver,
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
final LifecycleOwner mOwner;
LifecycleBoundObserver(LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
this.mOwner = owner;
}
//事件变化监听
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
//Fragment或者Activity onDestory()时移除监听,避免内存泄漏
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//生命周期事件变化将会在这里了进行处理
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
感知应用组件生命周期主要由LifecycleBoundObserver实现,配合Lifecycle的完成,当事件变化,判断数据是否应该通知观察者,并且当数据发生变化是,会判断当前observer状态是否active,只有active的情况才会通知相应的observer进行回调。
如何实现前言中实现的优势的呢?
有了上面的源码分析实现过程,我们一起来分析一下Livedata的这些优势是如何实现的呢?
1. 确保界面符合数据状态
观察者可以在每次发生更改时更新界面,而不是在每次应用数据发生更改时更新界面。这块主要是Lifecycle实现,当数据发生变化,有且只有Observer处于active状态才能接收回调处理。
2. 不会发生内存泄漏(observeForever方式不考虑)
observe()方法会绑定Lifecycle对象,由LifecycleBoundObserver完成,其中实现了LifecycleEventObserver,监听DESTROYED状态,当状态变成DESTROYED时候移除观察者。
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
//Fragment或者Activity onDestory()时移除监听,避免内存泄漏
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
//生命周期事件变化将会在这里了进行处理
activeStateChanged(shouldBeActive());
}
3. 不会因 Activity 停止而导致崩溃(observeForever方法不考虑)
观察者生命周期处于非活跃状态(如返回栈重难点Activity),不会接受任何LiveData事件。这块实现主要由:
private void considerNotify(ObserverWrapper observer) {
......
//非active状态不会进行回调处理,其中有LifecycleBoundObserver 的shouldBeActive()方法决定
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
......
//STARETED或者RESUMED才会 return ture
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
......
}
4. 不再需要手动处理生命周期(observeForever方法不考虑)
因为结合了Lifecycle对象,LiveData自动完成相关处理
5. 数据始终保持最新状态
当一个后台的Activity重新回到前台,如果LiveData的数据发生改变,会立即接受最新的数据。这一块主要由以下两块完成:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
//内容发生改变时,数据版本发生变化
mVersion++;
mData = value;
dispatchingValue(null);
}
private void considerNotify(ObserverWrapper observer) {
......
//非active状态不会进行回调处理,其中有LifecycleBoundObserver 的shouldBeActive()方法决定
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//如果obserer的数据版本会LiveData的最新数据版本不一致,则通知相应的观察者
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
......
//STARETED或者RESUMED才会 return ture
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
......
}
这里的实现过程有setValue是LiveData自身控制的mVersio和Observer.mLastVersion以及Lifecycle的生命周期事件变化共同控制完成。
6,适当的配置更改
如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据;
这里的实现需要配合ViewModel完成,ViewMode中存储LiveData,当配置更改是,ViewModel不会发生变化,但重新创建的Activity或者Fragment会重走生命周期,为LiveData添加新的Observer,因此立即接收最新的可用数据。
如何使用
优势,具体的原理了解后,就算修炼好了内功,遇到任何问题可以灵活应对,但同时我们需要修炼一些招式,从而更好的实际开发中进行快速、高效的使用;
基础使用
LiveData开发中用得更多的是其子类MutableLiveData
public class PersonViewModel extends ViewModel{
public MutableLiveData<Person> personLiveData = new MutableLiveData<>();
public void loadData(){
//you code
Person person = fromNet();
//update data
personLiveData.setValue(person);
}
}
public PersonFragment extends Fragment{
private PersonViewModel personViewModel;
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.personViewModel = new PersonViewModel(this, ViewModelProvider.AndroidViewModelFactory.getInstance(getApplication())).get(PersonViewModel.class);
this.personViewModel.personLiveData.observ(this,person -> {
// you code
})
}
}