livedata是乙個可觀察的資料儲存器。它可以通過觀察者observer與lifecycleowner配對來感知資料依附元件的生命週期狀態,只會把更新通知發給活躍的觀察者,所謂活躍就是觀察者處於started或者resumed狀態而沒有destroyed。
既然是資料儲存器,他是如何更新資料呢livedata有postvalue()和setvalue()方法去更新資料。postvalue(t value)可以在任意執行緒使用,setvalue(t value)只能在主線程更新資料。
postvalue(t value)原始碼:
protected void postvalue(t value)
if (!posttask)
//去主線程更新資料
archtaskexecutor.getinstance().posttomainthread(mpostvaluerunnable);
}private final runnable mpostvaluerunnable = new runnable()
//noinspection unchecked
setvalue((t) newvalue);
}};
通過postvalue(t value)原始碼我們可以知道他只是在多執行緒呼叫時候加了個鎖,然後最終還是通過setvalue(t value)去分發資料。
setvalue(t value)原始碼:
@mainthread
protected void setvalue(t value)
//為什麼setvalue中該方法引數會傳null,這要從該方法呼叫的兩種情況說起
//乙個情況就是setvalue 那就傳乙個null 去把資料更新到所有活躍的觀察者
//另乙個情況就是某乙個觀察者由不活躍狀態到活躍狀態 更新該觀察者對應的被觀察者
//知道了這兩種情況 這裡的**就好理解了
@suppresswarnings("weakeraccess") /* synthetic access */
if (mdispatchin**alue)
mdispatchin**alue = true;
do else }}
} while (mdispatchinvalidated);
mdispatchin**alue = false;
}//通知前會判斷觀察者是否活躍狀態,該更新資料是否是最新版本
if (!observer.mactive)
// 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())
if (observer.mlastversion >= mversion)
observer.mlastversion = mversion;
//noinspection unchecked
observer.mobserver.onchanged((t) mdata);
}
通過setvalue(t value)的原始碼,我們看到livedata在更新資料時會遍歷所有註冊的觀察者,只有活躍的觀察者才可以通知ui更新。
那livedata又是如何感知觀察者的活躍狀態呢首先我們來看livedata的使用示例**:
viewmodel.getdata().observe(this,object :observer>
})
通過observe方法的操作:
@mainthread
public void observe(@nonnull lifecycleowner owner, @nonnull observer<? super t> observer)
//observer和liferecycle完美結合 lifecycleboundobserver實現了lifecycleobserver
if (existing != null && !existing.isattachedto(owner))
if (existing != null)
}@nonnull
final lifecycleowner mowner;
lifecycleboundobserver(@nonnull lifecycleowner owner, observer<? super t> observer)
@override
boolean shouldbeactive()
//元件lifecycle生命週期狀態變化呼叫該方法 元件銷毀就移除該觀察者 元件起死回生就更新數
//據@override
public void onstatechanged(lifecycleowner source, lifecycle.event event)
activestatechanged(shouldbeactive());
}@override
boolean isattachedto(lifecycleowner owner)
@override
void detachobserver()
}void activestatechanged(boolean newactive)
// 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)
if (livedata.this.mactivecount == 0 && !mactive)
if (mactive)
}
原始碼看完誇兩句,livedata的優勢:
確保介面符合資料狀態
livedata 遵循觀察者模式。當生命週期狀態發生變化時,livedata 會通知observer
物件。您可以整合**以在這些observer
物件中更新介面。觀察者可以在每次發生更改時更新介面,而不是在每次應用資料發生更改時更新介面。
不會發生記憶體洩露
洩漏?不存在的,這輩子都不可能洩漏的!
不會因 activity 停止而導致崩潰
如果觀察者的生命週期處於非活躍狀態(如返回棧中的 activity),則它不會接收任何 livedata 事件。(非同步資料頁面關閉的view空指標)
不再需要手動處理生命週期
介面元件只是觀察相關資料,不會停止或恢復觀察。livedata 將自動管理所有這些操作,因為它在觀察時可以感知相關的生命週期狀態變化。
資料始終保持最新狀態
如果生命週期變為非活躍狀態,它會在再次變為活躍狀態時接收最新的資料。例如,曾經在後台的 activity 會在返回前台後立即接收最新的資料。
適當的配置更改
再也不用擔心橫豎屏元件重新裝件去儲存資料了。
共享資源
您可以使用單一例項模式擴充套件livedata
物件以封裝系統服務,以便在應用中共享它們。livedata
物件連線到系統服務一次,然後需要相應資源的任何觀察者只需觀察livedata
物件
react 入坑筆記(二) State
大致思想 在 react 中,每個元件都是乙個狀態機,通過與使用者的互動,實現不同狀態,然後渲染 ui,讓使用者介面和資料保持一致。react 裡,只需更新元件的 state,然後根據新的 state 重新渲染使用者介面 不要操作 dom class clock extends react.comp...
WSL入坑與踩坑
這篇文章,將會娓娓道來我使用wsl的經歷,包括如何安裝以及早期玩家踩的一些坑。這是乙個很好的工具,與vscode簡直是絕配。wsl是什麼 適用於 linux 的 windows 子系統可讓開發人員按原樣執行 gnu linux 環境 包括大多數命令列工具 實用工具和應用程式 且不會產生傳統虛擬機器或...
棄坑pexpect,入坑paramiko
上文書說到,ssh庫pexpect的使用,簡直就是個 月亮公主 滿眼全是坑。勉強把程式寫好了,跑起來的時候發現了乙個新坑,讓我不可抗拒的把它棄掉了 經常莫名其妙的連不上伺服器!開執行緒連線14臺伺服器,總有1到3臺連不上,還查不到原因。這還了得!一怒之下把寫好的pexpect封裝庫刪掉了,用para...