在兩個activity中分別對同一個集合做訂閱操作,當一個界面發(fā)送消息時,另一個面頁面打開時會有吐司,真正的方式是,在一個頁面發(fā)布消息,才會有吐司產(chǎn)生;那么現(xiàn)在的問題是在跳轉(zhuǎn)到第二個頁面剛訂閱沒有點擊吐司就出來了,是因為什么原因?qū)е碌哪兀可洗a
我們跟據(jù)上篇文章,來分析,通過with()獲取到一個liveData(),如果key相同,獲取到的就是同一個liveData;那么observe()方法中,會將當前activity和obersve放到一個邊界類中,并把邊界類放入到一個集合中()
上面的操作是關(guān)于訂閱,以及觀察者監(jiān)聽livedata數(shù)據(jù)變化的一個操作,那么什么時候出現(xiàn)了數(shù)值的變化,就在于livedata.postValue()做賦值操作,postvalue()->setvalue()->
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
? ? mVersion++;
? ? mData = value;
? ? dispatchingValue(null);
}
mVersion屬性是屬于liveData(),在每次進行setValue(),mVersion都會++,通過dispatchingValue()
最終找到了considerNotify()里onChanged()的調(diào)用,看下里面的判斷結(jié)果,如果observer的mLastVersion >=liveData的mVersion,那么結(jié)束操作,如果小于onChanged就會被調(diào)用,
實際操作就是在訂閱的時候,每個頁面都有一個observer監(jiān)聽,每個監(jiān)聽都有個屬性mLastVersion,mLastVersion的初始值是-1,但是這幾個頁面只針對一個liveData的存儲數(shù)據(jù)做操作,在第一次postValue時候,livedata的mversion已變成0,而在for()循環(huán)遍歷邊界集合時,第二個observer的mLastVersion是-1,所以代碼執(zhí)行到
if不符合條件就會觸發(fā)onChanged方法,所以第二個界面剛訂閱完,就彈出了吐司
解決方式,就是在第一次訂閱初始化的時候,把livedata的mVersion值賦值給observer的mLastVersion方法,這樣就能解決,單頁面訂閱-發(fā)布 不影響其他頁面
public static class BusMutableLiveDataextends MutableLiveData{
@Override
? ? public void observe(@NonNull LifecycleOwner owner, @NonNull Observer observer) {
super.observe(owner, observer);
? ? ? ? hook(observer);
? ? }
private void hook(Observer observer) {
try{
//1.得到mLastVersion
? ? ? ? ? ? Class liveDataClass=LiveData.class;
? ? ? ? ? ? Field mObserversField = liveDataClass.getDeclaredField("mObservers");
? ? ? ? ? ? mObserversField.setAccessible(true);
? ? ? ? ? ? //獲取到這個成員變量對應(yīng)的對象
? ? ? ? ? ? Object mObserversObject = mObserversField.get(this);
? ? ? ? ? ? //得到map
? ? ? ? ? ? Class mObserversObjectClass = mObserversObject.getClass();
? ? ? ? ? ? //獲取到mObservers對象的get方法
? ? ? ? ? ? Method get=mObserversObjectClass.getDeclaredMethod("get",Object.class);
? ? ? ? ? ? get.setAccessible(true);
? ? ? ? ? ? //執(zhí)行g(shù)et方法
? ? ? ? ? ? Object invokeEntry=get.invoke(mObserversObject,observer);
? ? ? ? ? ? //取到map中的value
? ? ? ? ? ? Object observerWraper=null;
? ? ? ? ? ? if(invokeEntry!=null && invokeEntryinstanceof Map.Entry){
observerWraper=((Map.Entry)invokeEntry).getValue();
? ? ? ? ? ? }
if(observerWraper==null){
throw new NullPointerException("observerWraper is null");
? ? ? ? ? ? }
//得到ObserverWrapper的類對象
? ? ? ? ? ? Class superclass=observerWraper.getClass().getSuperclass();
? ? ? ? ? ? Field mLastVersion = superclass.getDeclaredField("mLastVersion");
? ? ? ? ? ? mLastVersion.setAccessible(true);
? ? ? ? ? ? //2.得到mVersion
? ? ? ? ? ? Field mVersion = liveDataClass.getDeclaredField("mVersion");
? ? ? ? ? ? mVersion.setAccessible(true);
? ? ? ? ? ? //3.把mVersion的值填入到mLastVersion中
? ? ? ? ? ? Object mVersionValue=mVersion.get(this);
? ? ? ? ? ? mLastVersion.set(observerWraper,mVersionValue);
? ? ? ? }catch(Exception e){
e.printStackTrace();
? ? ? ? }
}
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。