简单地说,LiveData是一个数据持有类。它具有以下特点:
文中提到的“组件”皆指实现了LifecycleOwner接口Fragment、Activity。
从LiveData具有的特点,我们就能联想到它能够解决我们遇到的什么问题。LiveData具有以下优点:
注意项:
在了解LiveData定义和优点后,那它到底怎么应用呢?LiveData有几种使用方式:
使用LiveData对象主要有以下几个步骤:
void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer)
void observeForever(@NonNull Observer observer)
void postValue(T value)
void setValue(T value)
Android文档中建议LiveData配合ViewModel使用更加哦,其实呢,你也可以不使用ViewModel,但是一定要做到LiveData中保存的数据和组件分离,至于原因,前面我们已经提到过了。
下面是在ViewModel中创建LiveData实例的例子:
public class NameViewModel extends ViewModel{
// Create a LiveData with a String
private MutableLiveData<String> mCurrentName;
// Create a LiveData with a String list
private MutableLiveData<List<String>> mNameListData;
public MutableLiveData<String> getCurrentName() {
if (mCurrentName == null) {
mCurrentName = new MutableLiveData<>();
}
return mCurrentName;
}
public MutableLiveData<List<String>> getNameList(){
if (mNameListData == null) {
mNameListData = new MutableLiveData<>();
}
return mNameListData;
}
}
在NameViewModel中创建了两个MutableLiveData(MutableLiveData是LiveData的子类)实例,分别存储当前姓名、姓名列表;
两个实例通过NameViewModel中的getter方法得到。
public class LiveDataFragment extends Fragment {
private static final String TAG = "LiveDataFragment";
private NameViewModel mNameViewModel;
@BindView(R.id.tv_name)
TextView mTvName;
public static LiveDataFragment getInstance(){
return new LiveDataFragment();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mNameViewModel = ViewModelProviders.of(this).get(NameViewModel.class);
mNameViewModel.getCurrentName().observe(this,(String name) -> {
mTvName.setText(name);
Log.d(TAG, "currentName: " + name);
}); // 订阅LiveData中当前Name数据变化,以lambda形式定义Observer
mNameViewModel.getNameList().observe(this, (List<String> nameList) -> {
for (String item : nameList) {
Log.d(TAG, "name: " + item);
}
}); // 订阅LiveData中Name列表数据变化,以lambda形式定义Observer
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.layout_livedata, container, false);
ButterKnife.bind(this, view);
return view;
}
}
在onCreate()方法中通过LiveData.observe()方法添加观察者,当数据变化时会通过回调方法通知观察者,在lambda表达式中更新当前姓名和打印姓名列表。
在上面我们已经订阅了LiveData数据变化,现在我们看下如果LiveData数据变化时,上面的lambda表达式中是否会受到更新的通知。我们在LiveDataFragment中增加两个按钮来改变LiveData中的数据。
@OnClick({R.id.btn_change_name, R.id.btn_update_list})
void onClicked(View view){
switch (view.getId()){
case R.id.btn_change_name:
mNameViewModel.getCurrentName().setValue("Jane");
break;
case R.id.btn_update_list:
List<String> nameList = new ArrayList<>();
for (int i = 0; i < 10; i++){
nameList.add("Jane<" + i + ">");
}
mNameViewModel.getNameList().setValue(nameList);
break;
}
}
代码很简单,在两个按钮的点击事件中通过LiveData.setValue()方法来改变LiveData中保存的数据。当点击这两个按钮的时候,我们会发现在onCreate()方法中会收相应到数据改变的回调。
除了直接使用LiveDatad对象外,我们还可以通过集成LiveData类来定义适合特定需求的LiveData。
下面继承LiveData类的例子,验证下LiveData的其中一个优点——资源共享;
其中有两个点,实现了有需要的时候监听,没需要的时候不监听:
public class MyLiveData extends LiveData<Integer> {
private static final String TAG = "MyLiveData";
/******************************** 单例模式 ****************************/
private WeakReference<Context> mContextWeakReference;
private MyLiveData(Context context){
mContextWeakReference = new WeakReference<>(context);
}
private static MyLiveData sData;
public static MyLiveData getInstance(Context context){
if (sData == null){
sData = new MyLiveData(context);
}
return sData;
}
@Override
protected void onActive() {
super.onActive();
registerReceiver();
}
@Override
protected void onInactive() {
super.onInactive();
unregisterReceiver();
}
private void registerReceiver() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.RSSI_CHANGED_ACTION);
mContextWeakReference.get().registerReceiver(mReceiver, intentFilter);
}
private void unregisterReceiver() {
mContextWeakReference.get().unregisterReceiver(mReceiver);
}
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "action = " + action);
if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) {
int wifiRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200);
int wifiLevel = WifiManager.calculateSignalLevel(
wifiRssi, 4);
sData.setValue(wifiLevel);
}
}
};
}
Observer接口就是观察者,其中定义了LiveData数据变化的回调方法onChanged()
public interface Observer<T> {
/**
* Called when the data is changed.
* @param t The new data
*/
void onChanged(@Nullable T t);
}
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull final LifecycleOwner mOwner;
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
MediatorLiveData继承自MutableLiveData,MutableLiveData继承自LiveData。
MediatorLiveData可以看成是多个LiveData的代理,当将多个LiveData添加到MediatorLiveData,任何一个LiveData数据发生变化时,MediatorLiveData都会收到通知
public abstract class LiveData<T>
public class MutableLiveData<T> extends LiveData<T>
public class MediatorLiveData<T> extends MutableLiveData<T>
在Fragment/Activity中通过LiveData.observer()添加观察者(observer()方法中的第二个参数)
LiveData提供了两种添加观察者的方法:observeForever()、observe()。
@MainThread
public void observeForever(@NonNull Observer<T> observer) {
observe(ALWAYS_ON, observer);
}
observeForever()方法体很简单,调用了observe()方法,传入的一个参数是ALWAYS_ON常量,重点看下ALWAYS_ON常量是个啥东东。
private static final LifecycleOwner ALWAYS_ON = new LifecycleOwner() {
private LifecycleRegistry mRegistry = init();
private LifecycleRegistry init() {
LifecycleRegistry registry = new LifecycleRegistry(this);
registry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
registry.handleLifecycleEvent(Lifecycle.Event.ON_START);
registry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
return registry;
}
@Override
public Lifecycle getLifecycle() {
return mRegistry;
}
};
1.ALWAYS_ON是LifecycleOwner常量,在init方法中会初始化Lifecycle的生命周期状态。一直到Reumed状态
2. 完了之后,就没有改变过Lifecycle的生命周期状态了
这也就是为什么通过observeForever()添加观察者是,当数据改变时不管组件处于什么状态都会收到回调的原因,除非手动将观察者移除
private SafeIterableMap<Observer<T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<T> observer) {
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//将LifecycleOwner对象和Observer对象封装成LifecycleBoundObserver对象。
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// mObservers可以理解成一个类似Map的容器
//将 observer 作为 key,wrapper 作为 value 进行存储
//当 mObservers 不包含该 key 时,调用 putIfAbsent 会返回 null
//当 mObservers 已包含该 key 时,调用 putIfAbsent 不会存储 key-value,并会返回之前保存的 value
LifecycleBoundObserver existing = mObservers.putIfAbsent(observer, wrapper);
if (existing != null && existing.owner != wrapper.owner) {
//走到此步,说明之前 LiveData 内部已经持有了 observer 对象
//且该 observer 对象已经绑定了其它的 LifecycleOwner 对象
//此时直接抛出异常
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
//observer 之前已经传进来过了,此处直接返回
return;
}
owner.getLifecycle().addObserver(wrapper); //条件LifecycleOwner的生命周期观察者
}
onActive()
处于激活状态的observer个数从0到1onInactive()
处于激活状态的observer个数从1变为0dispatchingValue(this)
class LifecycleBoundObserver implements GenericLifecycleObserver {
public final LifecycleOwner owner;
public final Observer<T> observer;//外部传进来的对 LiveData 进行数据监听的 Observer
public boolean active;
public int lastVersion = START_VERSION;
LifecycleBoundObserver(LifecycleOwner owner, Observer<T> observer) {
this.owner = owner;
this.observer = observer;
}
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
// LifecycleOwner对象生命周期发生变化时,会通过该回调方法通知过来。
// 如果当前处于Lifecycle.State.DESTROYED时,会自动将观察者移除。
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(observer);
return;
}
// 判断是否处于actived状态,并将结果作为参数传递给activeStateChanged()
activeStateChanged(isActiveState(owner.getLifecycle().getCurrentState()));
}
void activeStateChanged(boolean newActive) {
if (newActive == active) { //新状态和之前状态相同,不处理
return;
}
active = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
LiveData.this.mActiveCount += active ? 1 : -1;
if (wasInactive && active) { //处于激活状态的observer个数从0到1
onActive();
}
if (LiveData.this.mActiveCount == 0 && !active) { //处于激活状态的observer个数从1变为0
onInactive();
}
if (active) {
dispatchingValue(this);
}
}
}
onActive()和onInactive()都是空实现的方法,继承类可以选择去实现。
我们看下dispatchingValue()方法的具体实现。
//用于标记当前是否正处于向 mObservers 发布 value 的过程
private boolean mDispatchingValue;
//用于标记当前正在发布的 value 是否已经失效
//在 value 还未向所有 Observer 发布完成的时候,新 value 已经到来,此时旧 value 就是处于失效状态
@SuppressWarnings("FieldCanBeLocal")
private boolean mDispatchInvalidated;
//initiator 为 null 则说明需要遍历回调整个 mObservers
//initiator 不为 null 则说明仅回调 initiator 本身
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
if (mDispatchingValue) {
//如果当前正处于向 mObservers 发布 mData 的过程中(即 mDispatchingValue 为 true)
//则将 mDispatchInvalidated 置为 true,用于标明有新值到来,正在回调的值是已经过时的了
mDispatchInvalidated = true;
return;
}
//用于标记当前正处于向 mObservers 发布 mData 的过程中
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) {
//如果 mDispatchInvalidated 为 true,则中断继续遍历过程
//用新值来重新循环一遍
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
//如果 observer 处于非活跃状态,则直接返回
if (!observer.mActive) {
return;
}
// Check latest state b4 dispatch. Maybe it changed state but we didn't get the event yet.
//
// we still first check observer.active to keep it as the entrance for events. So even if
// the observer moved to an active state, if we've not received that event, we better not
// notify for a more predictable notification order.
//此处判断主要是为了照顾 LifecycleBoundObserver
//由于 Lifecycle 有可能状态值 State 已经切换到了非活跃状态,但 LifecycleBoundObserver 还未收到事件通知
//所以为了避免意外情况,此处主动检查 observer 的活跃状态并判断是否需要更新其活跃状态
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//根据 observer 本部的 value 版本号 mLastVersion 来决定是否需要向其进行回调
//为了避免重复向某个 observer 回调值,所以此处需要判断下
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
observer.mObserver.onChanged((T) mData);
}
LiveData提供了两种改变数据的方法:setValue()和postValue()。区别是setValue()要在主线程中调用,而postValue()既可在主线程也可在子线程中调用。
我们先看setValue()方法的具体实现:
@MainThread
protected void setValue(T value) {
assertMainThread("setValue"); //判断当前线程是否是主线程,不是主线程就抛出异常
mVersion++;
mData = value;
dispatchingValue(null);
}
再看下postValue()方法的具体实现:
protected void postValue(T value) {
boolean postTask;
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
// 会在主线程中执行 mPostValueRunnable中的内容。
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
// 在主线程中调用setValue()方法
setValue((T) newValue);
}
};
postValue()方法通过ArchTaskExecutor实现在主线程中执行mPostValueRunnable对象中的内容,而在mPostValueRunnable中最终会调用setValue()方法来实现改变LiveData存储的数据
。