1、LiveData简介
- LiveData是一个具有生命周期感知特性的可观察的数据保持类,使用LiveData保存数据时,在每次订阅或数据更新时会自动回调设置的观察者从而更新数据,真正的实现了数据驱动的效果
- LiveData的创建基本会在ViewModel中,从而使数据在界面销毁时继续保持
- LiveData 认为观察者的生命周期处于STARTED状态或RESUMED状态下,表示观察者处于活动状态,LiveData只通知活跃的观察者更新数据
- 注册一个实现该LifecycleOwner 接口的对象配对的观察者,当相应Lifecycle对象的状态改变为DESTROYED时移除观察者
2,LiveData的使用
public class NameViewModel extends ViewModel {
//liveData通常和viewModel一起使用
private MutableLiveData<String> mCurrentName;
public MutableLiveData<String> getmCurrentName() {
if (mCurrentName == null) {
mCurrentName = new MutableLiveData<String>();
}
return mCurrentName;
}
}
public class FragmentOne extends Fragment {
private EditText edContent;
private Button btnSend;
private NameViewModel model;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_one, container, false);
edContent = view.findViewById(R.id.et_content);
btnSend = view.findViewById(R.id.btn_send);
//获取viewModel
model = ViewModelProviders.of(getActivity()).get(NameViewModel.class);
btnSend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//获取到liveData后设置liveData的值
model.getmCurrentName().setValue(edContent.getText().toString());
}
});
return view;
}
}
public class FragmentTwo extends Fragment {
private TextView textName;
private NameViewModel model;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_two, container, false);
textName = view.findViewById(R.id.tv_text);
//获取viewModel
model = ViewModelProviders.of(getActivity()).get(NameViewModel.class);
//监听值的变化
//model.getmCurrentName().observeForever();可以在任何时候得到数据
model.getmCurrentName().observe(getActivity(), new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
//更新UI
textName.setText(s);
}
});
return view;
}
}
通过model.getmCurrentName().setValue(edContent.getText().toString())改变livadata保存的值,再通过model.getmCurrentName().observe()方法注册观察者到LivaData对象上去。这样就能做到数据催动UI更新。
源码分析
@MainThread
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);
}
从第一步添加观察者observe方法开始,从参数中看到了LifecycleOwner,这里的作用是处理生命周期改变,在observe方法中执行了以下逻辑:
1.在observe中首先判断了当前Lifecycler的状态,当Destroy时即观察者不处于活跃状态,不用接收数据
2.创建LifecycleBoundObserver实例保存传入的LifecycleOwner和Observer,并保存在mObservers
3.添加LifecycleOwner的观察者,响应生命周期的变化
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
...
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
}
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
...
// 实现GenericLifecycleObserver 当生命周期改变时回调onStateChanged
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
...
}
上述执行的逻辑见代码中的注释,LifecycleBoundObserver主要利用Lifecycler的生命周期观察者GenericLifecycleObserver,前面设置了owner.getLifecycle().addObserver(wrapper)后,当生命周期改变时会回调onStateChange()方法,在生命周期为Destroy时移除Observer,在每次的生命周期变化时都会回调onStateChange(),然后调用shouldBeActive()判断当前活动是否出入活跃状态,shouldBeActive会根据Lifecycle中定义生命周期的顺序检测,只有当大于STARTED生命周期才为活跃,在activeStateChanged()也只会在活跃状态分发数据,然后调用dispatchingValue()分发数据.
@MainThread
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 {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
setValue()中调用了dispatchingValue(),在dispatchingValue中遍历mObservers中所有的Observer,调用considerNotify()更新数据,由前面知道所有的LifecycleBoundObserver对象都保存在mObservers集合中
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);
}
considerNotify()中调用mObserver的onChange()方法,这里的mObserver就是前面observe()中第二个参数的Observer,从而更新数据,简单就是说当LiveData中的数据改变时会遍历此LiveData所有的观察者,并回调onChange(),所以所有注册观察此数据的地方都会改变
总结:
LiveData整个过程就是两部分,一是使用LifeCycleOwner感知生命周期的变化,再一个就是储存并遍历Observer,在数据改变时回调所有的观察者。
网友评论