Jetpack入坑(二)LiveData原始碼分析

2021-10-05 12:30:17 字數 4249 閱讀 5337

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...