官方传送门
LiveData 是一种可观察的数据存储器类。与常规的可观察类不同,LiveData 具有生命周期感知能力,意指它遵循其他应用组件(如 Activity、Fragment 或 Service)的生命周期。这种感知能力可确保 LiveData 仅更新处于活跃生命周期状态的应用组件观察者。
添加依赖:
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:2.2.0"
LiveData类方法
public abstract class LiveData<T> {
//...以上省略...
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
//...以下省略...
}
LifecycleOwner 继承树:
Fragment和FragmentActivity都实现了LifecycleOwner 接口
LiveData类:
@Override
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//noinspection unchecked
setValue((T) newValue);
}
};
@Override
public void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
两个方法的区别:
postValue方法会运行在主线程
setValue方法会运行在当前线程
简单而言,使用postValue方法,调用的mObserver.onChanged()方法会运行在主线程;而setValue方法,调用的mObserver.onChanged()方法则可能会运行在主线程也可能运行在非主线程是当前线程而定。
postValue方法切换线程后最终会调用setValue方法。
//第一步:实例化LiveData
val liveData = MutableLiveData<ClipData.Item>()
//第二步:注册observer
liveData.observe(this, Observer<ClipData.Item> {
//执行回调
})
//第三步:传值
liveData.postValue(ClipData.Item("postValue"))
//或者
//liveData.setValue(ClipData.Item("postValue"))
每一次调用postValue或者setValue时,都会回调ObServe.onChange()方法。
至此,一个简单的LiveDataDemo已经完成。
简单分析一下LiveData原理
1、 注册:
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
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);
}
使用SafeIterableMap实例mObservers 存储observer对象。
2、传值(postValue/setValue)
setValue方法为例(postValue方法最终会调setValue方法)
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//遍历observe
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
//回调observe.onChange方法
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
调用setValue方法后,遍历mObservers,符合条件则回调observer.onChange方法。
官方传送门
ViewModel 类旨在以注重生命周期的方式存储和管理界面相关的数据。ViewModel 类让数据可在发生屏幕旋转等配置更改后继续留存。
添加ViewModel依赖:
implementation "androidx.lifecycle:lifecycle-viewmodel:2.2.0"
1、创建ViewModel实现类
public class SingleViewModel extends ViewModel {
private MutableLiveData<String> singleLiveData;
public MutableLiveData<String> getSingleLiveData() {
if (singleLiveData == null) {
singleLiveData = new MutableLiveData<String>();
}
return singleLiveData;
}
}
2、实例化ViewModel实例
//获取ViewModelProvider对象
public ViewModelProvider(@NonNull ViewModelStoreOwner owner) ;
//实例化ViewModel
public <T extends ViewModel> T get(@NonNull Class<T> modelClass);
3、为LiveData注册Observe
//Fragment中
var model = ViewModelProvider(requireActivity()).get(SingleViewModel::class.java)
//注册Observe
model.singleLiveData.observe(requireActivity(), Observer {
//回调
})
4、传值
model.singleLiveData.value = "click count ${count++}"
注意:
解析原理:
1、ViewModelStoreOwner
ViewModelStoreOwner的继承树:
public interface ViewModelStoreOwner {
/**
* Returns owned {@link ViewModelStore}
*
* @return a {@code ViewModelStore}
*/
@NonNull
ViewModelStore getViewModelStore();
}
FragmentActivity和Fragment都实现了ViewModelStoreOwner接口,换言之,都可以通过FragmentActivity或Fragment获取ViewModelStore 实例
2、 ViewModelStore
public class ViewModelStore {
private final HashMap<String, ViewModel> mMap = new HashMap<>();
//以下省略....
}
ViewModelStore通过HashMap存储ViewModel实例。
3、 ViewModelProvider
public class ViewModelProvider {
private static final String DEFAULT_KEY =
"androidx.lifecycle.ViewModelProvider.DefaultKey";
//...以上省略...
public <T extends ViewModel> T get(@NonNull Class<T> modelClass) {
String canonicalName = modelClass.getCanonicalName();
if (canonicalName == null) {
throw new IllegalArgumentException("Local and anonymous classes can not be ViewModels");
}
return get(DEFAULT_KEY + ":" + canonicalName, modelClass);
}
public <T extends ViewModel> T get(@NonNull String key, @NonNull Class<T> modelClass) {
//根据key获取ViewModel
ViewModel viewModel = mViewModelStore.get(key);
//以下代码实例化ViewModel
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);
}
//存储ViewModel
mViewModelStore.put(key, viewModel);
return (T) viewModel;
}
//...以下省略...
}
ViewModelProvider中的mViewModelStore通过ViewModelStoreOwner.getViewModelStore()方法获得,而FragmentActivity和Fragment都是ViewModelStoreOwner的实现类,隐藏,ViewModelProvider中的mViewModelStore可以通过FragmentActivity和Fragment获得。
注意:如果需要ViewModel可以在Activity和Fragment中通信需要保证ViewModelStoreOwner是相同的。
单独的LiveData没办法在Activity和Fragment间通信,必须与ViewModel结合才行。