1. 简介
LiveData是一个抽象类,MutableLiveData是其用的比较多的子类,在MutableLiveData中只是吧postValue和setValue方法的限制符改为public,以此来防止数据的混淆MediatorLiveData是liveData的聚集管理者。通过其来实现统一管理和中转。mVersion是一个同步标志类,liveData在做分发的时候,通过这个mVersion来控制是否应该进行数据的分发。
特性
- 确保UI符合数据状态
- 不需要手动处理数据
- 保持最新 的数据
eg
1. 基本使用首先,我们先写一个类继承我们的 ViewModel,里面持有 mNameEvent。
public class TestViewModel extends ViewModel {
private MutableLiveData<String> mNameEvent = new MutableLiveData<>();
public MutableLiveData<String> getNameEvent() {
return mNameEvent;
}
}
mTestViewModel = ViewModelProviders.of(this).get(TestViewModel.class);
MutableLiveData<String> nameEvent = mTestViewModel.getNameEvent();
nameEvent.observe(this, new Observer<String>() {
@Override
public void onChanged(@Nullable String s) {
Log.i(TAG, "onChanged: s = " + s);
mTvName.setText(s);
}
});
2. onActive() onInactive() 使用
public class NetworkLiveData extends LiveData<NetworkInfo> {
private final Context mContext;
static NetworkLiveData mNetworkLiveData;
private NetworkReceiver mNetworkReceiver;
private final IntentFilter mIntentFilter;
private static final String TAG = "NetworkLiveData";
public NetworkLiveData(Context context) {
mContext = context.getApplicationContext();
mNetworkReceiver = new NetworkReceiver();
mIntentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
}
public static NetworkLiveData getInstance(Context context) {
if (mNetworkLiveData == null) {
mNetworkLiveData = new NetworkLiveData(context);
}
return mNetworkLiveData;
}
@Override
protected void onActive() {
super.onActive();
Log.d(TAG, "onActive:");
mContext.registerReceiver(mNetworkReceiver, mIntentFilter);
}
@Override
protected void onInactive() {
super.onInactive();
Log.d(TAG, "onInactive: ");
mContext.unregisterReceiver(mNetworkReceiver);
}
private static class NetworkReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager manager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = manager.getActiveNetworkInfo();
getInstance(context).setValue(activeNetwork);
}
}
}
这样,当我们想监听网络变化的时候,我们只需要调用相应的 observe 方法即可,方便又快捷。
NetworkLiveData.getInstance(this).observe(this, new Observer<NetworkInfo>() {
@Override
public void onChanged(@Nullable NetworkInfo networkInfo) {
Log.d(TAG, "onChanged: networkInfo=" +networkInfo);
}
});
2. 类结构Structure
2.1 public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)通过该方法向liveData注册观察者对象
源码解析
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
assertMainThread("observe");
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
// 将LifecycleOwner 与 Observer 包装成 LifecycleBoundObserver
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 通过一个map保存一个个J键值对
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 方法不太一样的是,它在 Activity 处于 onPause ,onStop, onDestroy 的时候,都可以回调 obsever 的 onChange 方法,但是有一点需要注意的是,我们必须手动 remove obsever,否则会发生内存泄漏。
*/
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
wrapper.activeStateChanged(true);
}
- 这里将
LifecycleOwner和observer包装成一个LifecycleBoundObserver,LifecycleBoundObserver继承自ObserverWrapper和LifecycleEventObserver宿主的每一次生命周期的变化都会回调到onStateChanged里面 - 看其构造函数 在初始化的时候,其
mLastVersion = START_VERSION也就是说在初始化的时候,mLastVersion=-1,这为后续数据倒灌埋下了伏笔
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();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
// immediately set active state, so we'd never dispatch anything to inactive
// owner
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
dispatchingValue(this);
}
}
}
- 继续回到
liveData的addObserver中,owner.getLifecycle().addObserver跟进,会调用到LifecycleRegistry.addObserver()中,在这个方法中,又会将observer为state包装为ObserverWithState,并将其存入mObserverMap的map集合中
@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;
}
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++;
// 比对state
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
// 2. 分发Event
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--;
}
// 3. 跟进ObserverWithState 的dispatchEvent方法
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = event.getTargetState();
mState = min(mState, newState
// 4 其实就是在liveData调用addObserVer时,创建的LifecycleBoundObserver
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
回到LifecycleBoundObserver中的onStateChanged中
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
// 当当亲状态为DESTROYED时自行移除Observer
if (currentState == DESTROYED) {
// 反注册
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
// 活跃状态的变更
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
/**
*这里判断了只有当宿主的生命周期至少是isAtLeast(STARTED)时,才代表宿主是活跃的,也就是STARTED,RESUMED;
*
*/
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
- activeStateChanged()
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) {
// 没有活跃状态的observer
/**
* Called when the number of active observers change from 1 to 0.
* <p>
* This does not mean that there are no observers left, there may still be observers but their
* lifecycle states aren't {@link Lifecycle.State#STARTED} or {@link Lifecycle.State#RESUMED}
* (like an Activity in the back stack).
* <p>
* You can check if there are observers via {@link #hasObservers()}.
*/
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
- 因此我们可以在
onActive()中做一些初始化工作,在onInactive()中做一些反注册或者清理工作 - dispatchingValue(this); 真正执行
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;
}
private void considerNotify(ObserverWrapper 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.
// 判断宿主的生命周期
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 判断事件是否已经被分发
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
// 在这里就能看见我们熟悉的onChanged 方法了
observer.mObserver.onChanged((T) mData);
}
2.2 postValue(T value)和setValue(T value)
postValue(T value)如果是在子线程中,需要使用postValue 回调入主线程,其中使用到了一个有意思的工具类ArchTaskExecutor,也就是说以后我们想进行线程切换,或者执行任务,可以直接使用这个线程管理类 最终会走到这里
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
dispatchingValue(null);
}
- 遍历Map中的observer,调用 considerNotify(iterator.next().getValue());
- 美团LiveDataBus 原理就是从mObservers反射取出Observer,然后将livedata的mVersion赋值到Observer中
@SuppressWarnings("WeakerAccess") /* synthetic access */
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;
}
- 遍历Map中的observer,调用 considerNotify(iterator.next().getValue()); -比对Livedata的mVersion,和ObserverWrapper中的mLastVersion,如果mVersion>mLastVersion,调用onChanged()方法,将当前的mVersion赋值到mLastVersion
private void considerNotify(ObserverWrapper 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.
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//noinspection unchecked
observer.mObserver.onChanged((T) mData);
}
- activity重建时,数据倒灌的原因也在于此,因为viewModel中存的mVersion>obserserWapper.mLastVersion
3. 扩展应用LiveDataBus
package io.github.haodongling.lib.common.extention;
import java.util.concurrent.ConcurrentHashMap;
import androidx.annotation.NonNull;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.Observer;
public class LiveDataBus {
//
// Handler mHandler = new Handler(Looper.getMainLooper()){
// @Override
// public void handleMessage(@NonNull Message msg) {
// super.handleMessage(msg);
// }
// };
// mHandler.sendMessage(msg)
//正常的事件
// LiveData mLiveData=null;
// mLiveData.observer(this,new Observer<User>){
// void onChanged(User user){
//
// }
// }
//mLiveData.postValue(data);
//黏性事件。先发送。后注册监听
// LiveData mLiveData=null;
// mLiveData.postValue(data);
// mLiveData.observer(this,new Observer<User>){
// void onChanged(User user){
//
// }
// }
private static class Lazy {
static LiveDataBus sLiveDataBus = new LiveDataBus();
}
public static LiveDataBus get() {
return Lazy.sLiveDataBus;
}
private static ConcurrentHashMap<String, StickyLiveData> mHashMap = new ConcurrentHashMap<>();
public StickyLiveData with(String eventName) {
StickyLiveData liveData = mHashMap.get(eventName);
if (liveData == null) {
liveData = new StickyLiveData(eventName);
mHashMap.put(eventName, liveData);
}
return liveData;
}
/**
* 实际上liveData黏性事件总线的实现方式 还有另外一套实现方式。
* 一堆反射 获取LiveData的mVersion字段,来控制数据的分发与否,不够优雅。
* <p>
* 但实际上 是不需要那么干的。请看我们下面的实现方式。
*
* @param <T>
*/
public static class StickyLiveData<T> extends LiveData<T> {
private String mEventName;
private T mStickyData;
private int mVersion = 0;
public StickyLiveData(String eventName) {
mEventName = eventName;
}
/**
* 接收:observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer)
* @param value
*/
@Override
public void setValue(T value) {
mVersion++;
super.setValue(value);
}
@Override
public void postValue(T value) {
mVersion++;
super.postValue(value);
}
/**
* 接收: observerSticky(LifecycleOwner owner, Observer<? super T> observer, boolean sticky)
*/
public void setStickyData(T stickyData) {
this.mStickyData = stickyData;
setValue(stickyData);
}
public void postStickyData(T stickyData) {
this.mStickyData = stickyData;
postValue(stickyData);
}
@Override
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
observerSticky(owner, observer, false);
}
public void observerSticky(LifecycleOwner owner, Observer<? super T> observer, boolean sticky) {
super.observe(owner, new WrapperObserver(this, observer, sticky));
owner.getLifecycle().addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_DESTROY) {
mHashMap.remove(mEventName);
}
}
});
}
private class WrapperObserver<T> implements Observer<T> {
private StickyLiveData<T> mLiveData;
private Observer<T> mObserver;
private boolean mSticky;
//标记该liveData已经发射几次数据了,用以过滤老数据重复接收
private int mLastVersion = 0;
public WrapperObserver(StickyLiveData liveData, Observer<T> observer, boolean sticky) {
mLiveData = liveData;
mObserver = observer;
mSticky = sticky;
//比如先使用StickyLiveData发送了一条数据。StickyLiveData#version=1
//那当我们创建WrapperObserver注册进去的时候,就至少需要把它的version和 StickyLiveData的version保持一致
//用以过滤老数据,否则 岂不是会收到老的数据?
mLastVersion = mLiveData.mVersion;
}
@Override
public void onChanged(T t) {
//如果当前observer收到数据的次数已经大于等于了StickyLiveData发送数据的个数了则return
/**
* observer.mLastVersion >= mLiveData.mVersion
* 这种情况 只会出现在,我们先行创建一个liveData发射了一条数据。此时liveData的mversion=1.
*
* 而后注册一个observer进去。由于我们代理了传递进来的observer,进而包装成wrapperObserver,此时wrapperObserver的lastVersion 就会跟liveData的mversion 对齐。保持一样。把wrapperObserver注册到liveData中。
*
* 根据liveData的原理,一旦一个新的observer 注册进去,也是会尝试把数据派发给他的。这就是黏性事件(先发送,后接收)。
*
* 但此时wrapperObserver的lastVersion 已经和 liveData的version 一样了。由此来控制黏性事件的分发与否
*/
if (mLastVersion >= mLiveData.mVersion) {
//但如果当前observer它是关心 黏性事件的,则给他。
if (mSticky && mLiveData.mStickyData != null) {
mObserver.onChanged(mLiveData.mStickyData);
}
return;
}
mLastVersion = mLiveData.mVersion;
mObserver.onChanged(t);
}
}
}
}
使用方法
普通事件
- 创建一个Observer
private FeedObserver mFeedObserver;
private class FeedObserver implements Observer<Feed> {
private Feed mFeed;
@Override
public void onChanged(Feed newOne) {
if (mFeed.id != newOne.id)
return;
mFeed.author = newOne.author;
mFeed.ugc = newOne.ugc;
mFeed.notifyChange();
}
public void setFeed(Feed feed) {
mFeed = feed;
}
}
- 添加观察者
public static final String DATA_FROM_INTERACTION = "data_from_interaction";
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FeedDetailActivity.startFeedDetailActivity(mContext, feed, mCategory);
onStartFeedDetailActivity(feed);
if (mFeedObserver == null) {
mFeedObserver = new FeedObserver();
LiveDataBus.get()
.with(InteractionPresenter.DATA_FROM_INTERACTION)
.observe((LifecycleOwner) mContext, mFeedObserver);
}
mFeedObserver.setFeed(feed);
}
});
粘性事件
这里就只是粘贴一个postValue出来作为展示
if (response.body != null) {
boolean hasFavorite = response.body.getBooleanValue("hasFavorite");
feed.getUgc().setHasFavorite(hasFavorite);
LiveDataBus.get().with(DATA_FROM_INTERACTION)
.postValue(feed);
}
4. 注解使用
public class Ugc extends BaseObservable implements Serializable {
/**
* likeCount : 153
* shareCount : 0
* commentCount : 4454
* hasFavorite : false
* hasLiked : true
* hasdiss:false
*/
public int likeCount;
@Bindable
public int getShareCount() {
return shareCount;
}
public void setShareCount(int shareCount) {
this.shareCount = shareCount;
notifyPropertyChanged(BR._all);
}
public int shareCount;
public int commentCount;
public boolean hasFavorite;
public boolean hasdiss;
@Bindable
public boolean isHasdiss() {
return hasdiss;
}
public void setHasdiss(boolean hasdiss) {
if (this.hasdiss == hasdiss)
return;
if (hasdiss) {
setHasLiked(false);
}
this.hasdiss = hasdiss;
notifyPropertyChanged(BR._all);
}
public boolean hasLiked;
@Bindable
public boolean isHasLiked() {
return hasLiked;
}
public void setHasLiked(boolean hasLiked) {
if (this.hasLiked == hasLiked)
return;
if (hasLiked) {
likeCount = likeCount + 1;
setHasdiss(false);
} else {
likeCount = likeCount - 1;
}
this.hasLiked = hasLiked;
notifyPropertyChanged(BR._all);
}
@Override
public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj instanceof Ugc))
return false;
Ugc newUgc = (Ugc) obj;
return likeCount == newUgc.likeCount
&& shareCount == newUgc.shareCount
&& commentCount == newUgc.commentCount
&& hasFavorite == newUgc.hasFavorite
&& hasLiked == newUgc.hasLiked
&& hasdiss == newUgc.hasdiss;
}
@Bindable
public boolean isHasFavorite() {
return hasFavorite;
}
public void setHasFavorite(boolean hasFavorite) {
this.hasFavorite = hasFavorite;
notifyPropertyChanged(BR._all);
}
}
2. BaseObservable 全局更新
数据结构类继承BaseObservable,同时,在Field的get()方法上面标注@Bindable
这样就能在当数据改变是,通过调用 notifyPropertyChanged(BR._all);自动刷新
public class Feed extends BaseObservable implements Serializable {
public static final int TYPE_IMAGE_TEXT = 1;//图文
public static final int TYPE_VIDEO = 2;//视频
public int id;
public long itemId;
public int itemType;
public long createTime;
public double duration;
public String feeds_text;
public long authorId;
public String activityIcon;
public String activityText;
public int width;
public int height;
public String url;
public String cover;
public User author;
public Comment topComment;
public Ugc ugc;
@Bindable
public Ugc getUgc() {
if (ugc == null) {
ugc = new Ugc();
}
return ugc;
}
@Bindable
public User getAuthor() {
return author;
}
@Override
public boolean equals(@Nullable Object obj) {
if (obj == null || !(obj instanceof Feed))
return false;
Feed newFeed = (Feed) obj;
return id == newFeed.id
&& itemId == newFeed.itemId
&& itemType == newFeed.itemType
&& createTime == newFeed.createTime
&& duration == newFeed.duration
&& TextUtils.equals(feeds_text, newFeed.feeds_text)
&& authorId == newFeed.authorId
&& TextUtils.equals(activityIcon, newFeed.activityIcon)
&& TextUtils.equals(activityText, newFeed.activityText)
&& width == newFeed.width
&& height == newFeed.height
&& TextUtils.equals(url, newFeed.url)
&& TextUtils.equals(cover, newFeed.cover)
&& (author != null && author.equals(newFeed.author))
&& (topComment != null && topComment.equals(newFeed.topComment))
&& (ugc != null && ugc.equals(newFeed.ugc));
}
}