LiveData
是一个抽象类,MutableLiveData
是其用的比较多的子类,在MutableLiveData
中只是吧postValue和setValue方法的限制符改为public
,以此来防止数据的混淆MediatorLiveData
是liveData的聚集管理者。通过其来实现统一管理和中转。mVersion
是一个同步标志类,liveData
在做分发的时候,通过这个mVersion
来控制是否应该进行数据的分发。 public static Observer loginObserver(Observer observer, LiveData liveData) {
return new Observer() {
@Override
public void onChanged(User user) {
liveData.removeObserver(this);
if (user != null && observer != null) {
observer.onChanged(user);
}
}
};
}
livedata在使用后,记得移除
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);
}
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++;
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--;
}
/**
* 跟 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);
}
LifecycleBoundObserver.onStateChanged()
中 @Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
// 反注册
removeObserver(mObserver);
return;
}
activeStateChanged(shouldBeActive());
}
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.
*
* 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).
*
* You can check if there are observers via {@link #hasObservers()}.
*/
onInactive();
}
if (mActive) {
dispatchingValue(this);
}
}
onActive()
中做一些初始化工作,在onInactive()
中做一些反注册或者清理工作 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, 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);
}
public class TestViewModel extends ViewModel {
private MutableLiveData mNameEvent = new MutableLiveData<>();
public MutableLiveData getNameEvent() {
return mNameEvent;
}
}
mTestViewModel = ViewModelProviders.of(this).get(TestViewModel.class);
MutableLiveData nameEvent = mTestViewModel.getNameEvent();
nameEvent.observe(this, new Observer() {
@Override
public void onChanged(@Nullable String s) {
Log.i(TAG, "onChanged: s = " + s);
mTvName.setText(s);
}
});
onActive()
onInactive()
使用public class NetworkLiveData extends LiveData {
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() {
@Override
public void onChanged(@Nullable NetworkInfo networkInfo) {
Log.d(TAG, "onChanged: networkInfo=" +networkInfo);
}
});
postValue(T value)
和setValue(T value)
postValue(T value)
如果是在子线程中,需要使用postValue 回调入主线程,其中使用到了一个有意思的工具类ArchTaskExecutor
,也就是说以后我们想进行线程切换,或者执行任务,可以直接使用这个线程管理类LiveDataBus
public class LiveDataBus {
private static class Lazy {
static LiveDataBus sLiveDataBus = new LiveDataBus();
}
public static LiveDataBus get() {
return Lazy.sLiveDataBus;
}
private static ConcurrentHashMap 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字段,来控制数据的分发与否,不够优雅。
*
* 但实际上 是不需要那么干的。请看我们下面的实现方式。
*
* @param
*/
public static class StickyLiveData extends LiveData {
private String mEventName;
private T mStickyData;
private int mVersion = 0;
public StickyLiveData(String eventName) {
mEventName = eventName;
}
@Override
public void setValue(T value) {
mVersion++;
super.setValue(value);
}
@Override
public void postValue(T value) {
mVersion++;
super.postValue(value);
}
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 implements Observer {
private StickyLiveData mLiveData;
private Observer mObserver;
private boolean mSticky;
//标记该liveData已经发射几次数据了,用以过滤老数据重复接收
private int mLastVersion = 0;
public WrapperObserver(StickyLiveData liveData, Observer 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);
}
}
}
}
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);
}
}
数据结构类继承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));
}
}