Livedata
LiveData
LiveData优点
- 确保界面符合数据状态
LiveData 遵循观察者模式。当生命周期状态发生变化时,LiveData 会通知 Observer
对象。您可以整合代码以在这些 Observer
对象中更新界面。观察者可以在每次发生更改时更新界面,而不是在每次应用数据发生更改时更新界面。
- 不会发生内存泄漏
观察者会绑定到 Lifecycle
对象,并在其关联的生命周期遭到销毁后进行自我清理
- 不会因 Activity 停止而导致崩溃
如果观察者的生命周期处于非活跃状态(如返回栈中的 Activity),则它不会接收任何 LiveData 事件。
- 不再需要手动处理生命周期
界面组件只是观察相关数据,不会停止或恢复观察。LiveData 将自动管理所有这些操作,因为它在观察时可以感知相关的生命周期状态变化。
- 数据始终保持最新状态
如果生命周期变为非活跃状态,它会在再次变为活跃状态时接收最新的数据。例如,曾经在后台的 Activity 会在返回前台后立即接收最新的数据。
- 适当的配置更改
如果由于配置更改(如设备旋转)而重新创建了 Activity 或 Fragment,它会立即接收最新的可用数据。
- 共享资源
您可以使用单一实例模式扩展 LiveData 对象以封装系统服务,以便在应用中共享它们。LiveData
对象连接到系统服务一次,然后需要相应资源的任何观察者只需观察 LiveData
对象
LiveData原理分析
LiveData本质上就是基于Lifecycle来实现的。观察LiveData从源码上来说就是通过传入的LifecycleOwner(Activity/Fragment)获取到LifecycleRegistry,通过它的addObserver方法向其中添加了一个LifecycleObserver的实现类。也就是说它是基于Lifecycle实现的。
简单使用:
一般我们会在Activity或Fragment中调用LiveData的observe函数
mViewModel.dataList.observe(viewLifecycleOwner, Observer {
...
}
LiveData.observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe"); //必须在主线程观察LiveData
//如果LifecycleOwner的当前状态为DESTROYED,也就是已经被销毁了,就直接返回
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//将LifecycleOwner和Observer封装到LifecycleBoundObserver中
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;
}
//getLifecycle方法获取LifecycleOwner持有的LifecycleRegistry,调用它的addObserver方法将LifecycleBoundObserver
owner.getLifecycle().addObserver(wrapper);
}
从上面的代码可以看出,LiveData的observe方法本质上就是通过传入的LifecycleOwner获取到LifecycleRegistry,通过它的addObserver方法向其中添加了一个LifecycleObserver的实现类。也就是说它是基于Lifecycle实现的。
LifecycleRegistry.addObserver()
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
if (previous != null) {
return;
}
//获取LifecycleRegistry通过弱引用持有的LifecycleOwner对象,如果它为null,说明已经销毁并被GC
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
if (lifecycleOwner == null) {
// it is null we should be destroyed. Fallback quickly
return;
}
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState / subling may have been changed recalculate
targetState = calculateTargetState(observer);
}
if (!isReentrance) {
// we do sync only on the top level.
sync();
}
mAddingObserverCounter--;
}
Transformation.map()和Transformation.switchMap()
Transformation.map()
作用:通过对传入的LiveData应用转换函数,将其转换为其他类型的一个新的LiveData对象。新对象是基于并通过原对象转换生成的。
简单使用
LiveData<User> userLiveData = ...;
LiveData<String> userFullNameLiveData =
Transformations.map(
userLiveData,
user -> user.firstName + user.lastName);
});
Transformation.switchMap()
作用:每当传入的LiveData发生变化时,就会将转换函数中返回的LiveData对象转换为一个新的LiveData对象。
使用场景
ViewModel中的某个LiveData对象是调用另外的方法来获取的,那么就可以将这个LiveData对象转换为另一个LiveData对象。
简单使用
class UserViewModel extends AndroidViewModel {
MutableLiveData<String> nameQueryLiveData = ...
LiveData<List<String>> getUsersWithNameLiveData() {
return Transformations.switchMap(
nameQueryLiveData,
name -> myDataSource.getUsersWithNameLiveData(name));
}
void setNameQuery(String name) {
this.nameQueryLiveData.setValue(name);
}
}