1 簡介和簡單使用
1.1 簡介
LiveData是一種可觀察的數(shù)據(jù)存儲器類冠场。與常規(guī)的可觀察類不同,LiveData具有生命周期感知能力,意指它遵循其他應(yīng)用組件(如Activity娃肿、Fragment或Service)的生命周期晒杈。這種感知能力可確保LiveData僅更新處于活躍生命周期(onStart粪般、onResume)狀態(tài)的應(yīng)用組件觀察者。LiveData通常和ViewModel相結(jié)合使用。
LiveData依賴于Lifecycle,需要使用Lifecycle提供的狀態(tài)來判斷程序的活躍狀態(tài)滔蝉。
如果觀察者(由Observer類表示)的生命周期處于STARTED或RESUMED狀態(tài)螃概,則LiveData會認(rèn)為該觀察者處于活躍狀態(tài)冒窍。LiveData 只會將更新通知給活躍的觀察者。為觀察LiveData對象而注冊的非活躍觀察者不會收到更改通知圣猎。
Google官網(wǎng):https://developer.android.google.cn/topic/libraries/architecture/livedata?hl=zh_cn
1.2 簡單使用
引入依賴,按需所取应狱。
def lifecycle_version = "2.4.1"
def arch_version = "2.1.0"
// ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version"
// LiveData
implementation "androidx.lifecycle:lifecycle-livedata:$lifecycle_version"
// Lifecycles only (without ViewModel or LiveData)
implementation "androidx.lifecycle:lifecycle-runtime:$lifecycle_version"
// Saved state module for ViewModel
implementation "androidx.lifecycle:lifecycle-viewmodel-savedstate:$lifecycle_version"
// Annotation processor
annotationProcessor "androidx.lifecycle:lifecycle-compiler:$lifecycle_version"
// alternately - if using Java8, use the following instead of lifecycle-compiler
implementation "androidx.lifecycle:lifecycle-common-java8:$lifecycle_version"
// optional - helpers for implementing LifecycleOwner in a Service
implementation "androidx.lifecycle:lifecycle-service:$lifecycle_version"
// optional - ProcessLifecycleOwner provides a lifecycle for the whole application process
implementation "androidx.lifecycle:lifecycle-process:$lifecycle_version"
// optional - ReactiveStreams support for LiveData
implementation "androidx.lifecycle:lifecycle-reactivestreams:$lifecycle_version"
// optional - Test helpers for LiveData
testImplementation "androidx.arch.core:core-testing:$arch_version"
創(chuàng)建一個單例StrLiveData年缎,里邊會實例化一個MutableLiveData坛怪,用來存儲String類型的數(shù)據(jù)怪嫌。
object StrLiveData {
//懶加載
val info: MutableLiveData<String> by lazy { MutableLiveData() }
}
在Activity中使用找爱。
class LiveDataActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_data)
val tvContent = findViewById<TextView>(R.id.tv_content)
//觀察數(shù)據(jù)變化敞贡,界面可見時迫悠,才會給TextView設(shè)置數(shù)據(jù)
StrLiveData.info.observe(this) {
tvContent.text = it
}
//觀察數(shù)據(jù)變化搁拙,不管界面可見不可見字柠,都給TextView設(shè)置數(shù)據(jù)
//observeForever不會考慮生命周期铜异,任何狀態(tài)下都會執(zhí)行
StrLiveData.info.observeForever {
tvContent.text = it
}
//主線程修改數(shù)據(jù)
StrLiveData.info.value = "在主線程修改的數(shù)據(jù)"
thread {
Thread.sleep(2000)
//子線程修改數(shù)據(jù)
StrLiveData.info.postValue("在子線程修改的數(shù)據(jù)")
}
}
}
XML文件。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
tools:context=".jetpack.livedata.demo1.LiveDataActivity">
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
1.3 關(guān)系框架
2 源碼分析
2.1 setValue 主線程修改數(shù)據(jù)
首先在業(yè)務(wù)層單例中實例化了一個MutableLiveData食茎,MutableLiveData繼承LiveData惧互,只保留setValue和postValue兩個設(shè)置數(shù)據(jù)的方法管宵,簡化使用钱床。
public class MutableLiveData<T> extends LiveData<T> {
/**
* Creates a MutableLiveData initialized with the given {@code value}.
*
* @param value initial value
*/
public MutableLiveData(T value) {
super(value);
}
/**
* Creates a MutableLiveData with no value assigned to it.
*/
public MutableLiveData() {
super();
}
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
當(dāng)業(yè)務(wù)層調(diào)用LiveData的setValue方法時,在主線程修改數(shù)據(jù)慌盯。
//主線程修改數(shù)據(jù)
StrLiveData.info.value = "在主線程修改的數(shù)據(jù)"</pre>
setValue方法首先會檢查當(dāng)前是否是主線程,然后會對mVersion+1掂器,接著分發(fā)數(shù)據(jù)润匙。
<pre data-language="java" id="QU8SA" class="ne-codeblock language-java" style="border: 1px solid #e8e8e8; border-radius: 2px; background: #f9f9f9; padding: 16px; font-size: 13px; color: #595959">@MainThread
protected void setValue(T value) {
//檢查是否是主線程
assertMainThread("setValue");
//mVersion+1
mVersion++;
mData = value;
//分發(fā)數(shù)據(jù)
dispatchingValue(null);
}
mVersion是LiveData粘性數(shù)據(jù)特性的關(guān)鍵,它的初始值是-1唉匾。
static final int START_VERSION = -1;
public LiveData() {
mData = NOT_SET;
//LiveData實例化的時候給mVersion賦值為-1
mVersion = START_VERSION;
}
分發(fā)數(shù)據(jù)的時候有兩種情況,一種是調(diào)用LiveData.observe()匠楚,另一種是調(diào)用LiveData.observeForever()巍膘。ObserverWrapper是觀察者的包裝類。
void dispatchingValue(@Nullable ObserverWrapper initiator) {
...
//initiator(觀察者)不為空
if (initiator != null) {
considerNotify(initiator);
initiator = null;
} else {
//initiator(觀察者)為空芋簿,需要遍歷所有的觀察者
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
...
}
接下來調(diào)用considerNotify方法峡懈。然后對當(dāng)前是否是活躍狀態(tài)進行檢查,也就是mActive是否為true与斤。為true才會繼續(xù)執(zhí)行肪康。就這對mVersion進行對比,由于在setValue的時候mVersion++之后變?yōu)?撩穿,mLastVersion為-1磷支,所以這里observer.mLastVersion >= mVersion不成立,數(shù)據(jù)會正常分發(fā)出去食寡,這就是造成粘性數(shù)據(jù)特征的原因雾狈。
如果調(diào)用LiveData.observe(),那么當(dāng)Lifecycle狀態(tài)為STARTED和RESUMED抵皱,也就是Activity/Fragment生命周期為onStart和onResume的時候善榛,mActive=true辩蛋,其他狀態(tài)和生命周期下,mActive=fale移盆;如果調(diào)用LiveData.observeForever()悼院,mActive一直為true,這就實現(xiàn)了調(diào)用LiveData.observeForever()時候咒循,觀察者不會去考慮生命周期和狀態(tài)据途,所有數(shù)據(jù)都會無條件感知。
private void considerNotify(ObserverWrapper observer) {
if (!observer.mActive) {
return;
}
//判斷mActivie是否為true剑鞍。
//調(diào)用LiveData.observe()時會根據(jù)狀態(tài)和生命周期計算mActive的值;
//調(diào)用LiveData.observeForever()時mActive一直為true昨凡。
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
//判斷mVersion
if (observer.mLastVersion >= mVersion) {
return;
}
observer.mLastVersion = mVersion;
//回調(diào)數(shù)據(jù)給觀察者
observer.mObserver.onChanged((T) mData);
}
2.2 postValue 子線程修改數(shù)據(jù)
當(dāng)業(yè)務(wù)層調(diào)用LiveData的postValue方法時,在子線程修改數(shù)據(jù)蚁署。
thread {
...
//子線程修改數(shù)據(jù)
StrLiveData.info.postValue("在子線程修改的數(shù)據(jù)")
}
postValue方法中最終也會通過Handler切換到主線程便脊。
protected void postValue(T value) {
boolean postTask;
//加鎖,防止線程安全問題
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
if (!postTask) {
return;
}
//切換到主線程
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
在ArchTaskExecutor中光戈,會實例化一個DefaultTaskExecutor哪痰,然后調(diào)用DefaultTaskExecutor的postToMainThread方法。
private ArchTaskExecutor() {
mDefaultTaskExecutor = new DefaultTaskExecutor();
mDelegate = mDefaultTaskExecutor;
}
@Override
public void postToMainThread(Runnable runnable) {
mDelegate.postToMainThread(runnable);
}
DefaultTaskExecutor使用Handler進行線程間通信久妆,實現(xiàn)子線程到主線程切換晌杰。
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
mMainHandler = new Handler(Looper.getMainLooper());
}
}
}
//noinspection ConstantConditions
mMainHandler.post(runnable);
}
而在postToMainThread中傳入的Runnable中,最紅也調(diào)用了setValue筷弦,接下來的邏輯就和主線程中修改數(shù)據(jù)一致了肋演。
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//最終也是調(diào)用setValue
setValue((T) newValue);
}
};
2.3 observe 根據(jù)生命周期感知數(shù)據(jù)變化
調(diào)用LiveData的observe( LifecycleOwner owner, Observer<? super T> observer)方法時,傳入了一個被觀察者和觀察者烂琴。
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//檢查是否是主線程
assertMainThread("observe");
//獲取Lifecycle當(dāng)前狀態(tài)爹殊,如果是銷毀狀態(tài),那就忽略奸绷,不再繼續(xù)往下進行
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
return;
}
//創(chuàng)建一個LifecycleBoundObserver對象梗夸,包裝了LifecycleOwner和Observer。
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//ObserverWrapper包裝了LifecycleBoundObserver和Observer
//把Observer和LifecycleBoundObserver存入map
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);
}
LifecycleBoundObserver是LiveData的內(nèi)部類号醉,繼承了ObserverWrapper反症,并且實現(xiàn)LifecycleObserver。傳入了一個被觀察者和觀察者畔派。
class LifecycleBoundObserver extends ObserverWrapper implements LifecycleEventObserver {
@NonNull
final LifecycleOwner mOwner;
//傳入被觀察者和觀察者
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
@Override
boolean shouldBeActive() {
//從Lifecycle獲取到當(dāng)前是否是活躍狀態(tài)(UI可見狀態(tài))铅碍。
//Activity/Fragment生命周期onStart和onResume,Lifecycle對應(yīng)狀態(tài)為STARTED和RESUMED時线椰,處于活躍狀態(tài)该酗。
//這里使用了一個比較,也就是狀態(tài)在STARTED和STARTED之后時,就處于活躍狀態(tài)呜魄。
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
Lifecycle.State currentState = mOwner.getLifecycle().getCurrentState();
if (currentState == DESTROYED) {
//頁面銷毀時悔叽,移除觀察者
removeObserver(mObserver);
return;
}
Lifecycle.State prevState = null;
while (prevState != currentState) {
prevState = currentState;
//調(diào)用ObserverWrapper的activeStateChanged,再調(diào)用dispatchingValue分發(fā)數(shù)據(jù)爵嗅。
activeStateChanged(shouldBeActive());
currentState = mOwner.getLifecycle().getCurrentState();
}
}
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
@Override
void detachObserver() {
//觀察者和被觀察者解除綁定
mOwner.getLifecycle().removeObserver(this);
}
}
ObserverWrapper是LiveData的抽象內(nèi)部類娇澎。
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
//抽象方法,判斷是否處于活躍狀態(tài)
abstract boolean shouldBeActive();
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {
}
void activeStateChanged(boolean newActive) {
if (newActive == mActive) {
return;
}
mActive = newActive;
changeActiveCounter(mActive ? 1 : -1);
if (mActive) {
//處于活躍狀態(tài)睹晒,發(fā)送最新的值
dispatchingValue(this);
}
}
}
2.3 observeForever 無條件感知數(shù)據(jù)變化
在調(diào)用LiveData的observeForever方法時趟庄,沒有傳入被觀察者,值傳入了觀察者伪很,這就決定了調(diào)用observeForever之后無法根據(jù)Activity/Fragment的生命周期去判斷合適感知數(shù)據(jù)戚啥,只能無條件的接收所有數(shù)據(jù)。這里用AlwaysActiveObserver對觀察者進行了包裝锉试。
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
//判斷是否是主線程
assertMainThread("observeForever");
//創(chuàng)建一個AlwaysActiveObserver對象猫十,對Observer進行包裝
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
//ObserverWrapper包裝了AlwaysActiveObserver和Observer
//把Observer和AlwaysActiveObserver存入map
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;
}
//這里傳入的mActive一直是true,所以消息一直能無條件回調(diào)給觀察者
wrapper.activeStateChanged(true);
}
再看AlwaysActiveObserver呆盖,shouldBeActive固定返回true拖云。所以在considerNotify方法中,一直能執(zhí)行到observer.mObserver.onChanged((T) mData)应又,把數(shù)據(jù)回調(diào)給觀察者宙项。
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
@Override
boolean shouldBeActive() {
return true;
}
}
3 流程圖
根據(jù)上邊的源碼分析,畫出以下流程圖株扛。
關(guān)注木水小站 (zhangmushui.cn)和公眾號【木水Code】尤筐,及時獲取更多技術(shù)干貨。