有時(shí)候,靠單純的判斷并不能確定成功的幾率秆吵。與其在等待中浪費(fèi)青春,不如在追求中燃燒生命五慈∧杉牛——《狼道》
目錄
前言
一、簡介
二泻拦、基本使用
三毙芜、源碼分析
四、內(nèi)容推薦
五争拐、項(xiàng)目參考
前言
——這篇記錄的是一個(gè)常用的Jetpack架構(gòu)組件之一的LiveData腋粥。通俗講它有兩個(gè)顯著作用:1.通過觀察者模式當(dāng)數(shù)據(jù)發(fā)生變化的時(shí)候通知UI更新。2.與生命周期綁定在一起架曹,當(dāng)組件生命周期發(fā)生變化處于激活時(shí)通知UI更新隘冲。這么說可能還有點(diǎn)不清晰,具體請看下文分解:
一绑雄、簡介
(1)是什么
——LiveData是一個(gè)可觀察的數(shù)據(jù)持有者類展辞。與常規(guī)的可觀察對象不同,LiveData是生命周期感知的万牺,這意味著它尊重其他應(yīng)用程序組件(如活動(dòng)罗珍、片段或服務(wù))的生命周期洽腺。這種意識確保LiveData只更新處于活動(dòng)生命周期狀態(tài)的應(yīng)用程序組件觀察者。
(2)有什么用
數(shù)據(jù)可以被觀察者訂閱
能夠感知組件(Fragment覆旱、Activity蘸朋、Service)的生命周期
只有在組件出于激活狀態(tài)(STARTED、RESUMED)才會通知觀察者有數(shù)據(jù)更新
(3)有什么優(yōu)點(diǎn)
能夠保證數(shù)據(jù)和UI統(tǒng)一
減少內(nèi)存泄漏
當(dāng)Activity停止時(shí)不會引起崩潰
不需要額外的手動(dòng)處理來響應(yīng)生命周期的變化
組件和數(shù)據(jù)相關(guān)的內(nèi)容能實(shí)時(shí)更新
針對configuration change時(shí)扣唱,不需要額外的處理來保存數(shù)據(jù)
資源共享
?二藕坯、基本使用
(4)怎么使用
LiveData的使用方式有兩種:1.使用LiveData對象;2.繼承LiveData類
- 使用LiveData對象
實(shí)現(xiàn)步驟:
1.創(chuàng)建一個(gè)LiveData實(shí)例來保存數(shù)據(jù)
2.創(chuàng)建Observer監(jiān)聽數(shù)據(jù)改變
3.設(shè)置值,如果有活動(dòng)的觀察者,值將被發(fā)送給他們
//創(chuàng)建一個(gè)定義onChanged()方法的觀察者對象,該方法控制LiveData對象持有的數(shù)據(jù)更改時(shí)發(fā)生的情況画舌。
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 1.創(chuàng)建一個(gè)LiveData實(shí)例來保存數(shù)據(jù)
MutableLiveData<String> currentName = new MutableLiveData<String>();
// 2.創(chuàng)建Observer監(jiān)聽數(shù)據(jù)改變
final Observer<String> nameObserver = new Observer<String>() {
@Override
public void onChanged(@Nullable final String newName) {
//更新UI操作
nameTextView.setText(newName);
}
};
// 添加Observer
currentName.observe(this, nameObserver);
}
public void onClick(View view){
// 3.設(shè)置值 如果有活動(dòng)的觀察者 值將被發(fā)送給他們
//主線程使用setValue
model.getCurrentName().setValue("xxxx")
//后臺線程使用postValue
//model.getCurrentName().postValue("xxxx")
}
}
- 繼承LiveData類
//Demo1擴(kuò)展LiveData類(監(jiān)聽網(wǎng)絡(luò)狀態(tài))
public class NetworkLiveData extends LiveData<NetworkInfo> {
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();
//當(dāng)組件處于激活狀態(tài)時(shí)注冊廣播
mContext.registerReceiver(mNetworkReceiver, mIntentFilter);
}
@Override
protected void onInactive() {
super.onInactive();
//當(dāng)組件處于銷毀狀態(tài)時(shí)注銷廣播
mContext.unregisterReceiver(mNetworkReceiver);
}
//監(jiān)聽網(wǎng)絡(luò)狀態(tài)
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);
}
}
}
//使用過程
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
NetworkLiveData.getInstance(this).observe(this,new Observer(){
@Override
public void onChanged(@Nullable final String newName) {
// Update UI
}
})
}
}
LiveData的使用方式相對比較簡單堕担。實(shí)現(xiàn)方式也比較容易。就不描述太多細(xì)節(jié)曲聂。相信大家看代碼會比看解釋更容易理解霹购。
三、源碼分析
——因?yàn)長iveData是抽象類朋腋,所以我們要使用它就需要寫一個(gè)類來繼承LiveData齐疙。
——當(dāng)然系統(tǒng)也幫我們寫了幾個(gè)可直接使用的類,MutableLiveData,MediatorLiveData旭咽。
1.MutableLiveData源碼
// 創(chuàng)建了一個(gè)MutableLiveData實(shí)例
MutableLiveData<String> liveData = new MutableLiveData<>();
// MutableLiveData源碼
public class MutableLiveData<T> extends LiveData<T> {
@Override
public void postValue(T value) {
super.postValue(value);
}
@Override
public void setValue(T value) {
super.setValue(value);
}
}
——MutableLiveData把LiveData的postValue方法與setValue接口暴露出來可供調(diào)用贞奋。這個(gè)后面使用的時(shí)候在分析
2.LiveData的observe源碼
//創(chuàng)建Observer監(jiān)聽數(shù)據(jù)改變
liveData.observe(this, new Observer<String>() {
@Override
public void onChanged(String s) {
binding.setName(s);
}
});
(1)observe源碼
//該方法主要把observer與Activity(組件)的生命周期綁定在一起。當(dāng)Activity(組件)狀態(tài)改變的時(shí)候通知observer
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
//請看(5)
assertMainThread("observe");
//當(dāng)前Activity(組件)狀態(tài)處于銷毀狀態(tài)時(shí) 是則返回
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// ignore
return;
}
//請看(2)
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
//以鍵值對的形式存儲observer于LifecycleBoundObserver穷绵,如果LifecycleBoundObserver已經(jīng)存儲過則ObserverWrapper返回空
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
//判斷是否是同一個(gè)LifecycleOwner
if (existing != null && !existing.isAttachedTo(owner)) {
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
//這里攔截已經(jīng)添加過的LifecycleBoundObserver
if (existing != null) {
return;
}
//添加一個(gè)wrapper轿塔,它將在LifecycleOwner狀態(tài)更改時(shí)得到通知 具體原理可以看樓主Lifecycle原理篇
owner.getLifecycle().addObserver(wrapper);
}
(2)LiveData的內(nèi)部類LifecycleBoundObserver源碼
//該類通過實(shí)現(xiàn)GenericLifecycleObserver監(jiān)聽生命周期變化更新Observer傳遞的數(shù)據(jù)
//繼承ObserverWrapper根據(jù)Activity(組件)的生命周期管理著Observer
class LifecycleBoundObserver extends ObserverWrapper implements GenericLifecycleObserver {
@NonNull
final LifecycleOwner mOwner;
//observer傳給ObserverWrapper的構(gòu)造函數(shù)
LifecycleBoundObserver(@NonNull LifecycleOwner owner, Observer<? super T> observer) {
super(observer);
mOwner = owner;
}
//返回當(dāng)前Activity(組件)的生命狀態(tài)是否是STARTED或者RESUMED
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
//通過實(shí)現(xiàn)GenericLifecycleObserver接口的onStateChanged方法監(jiān)聽Activity(組件)生命周期變化
@Override
public void onStateChanged(LifecycleOwner source, Lifecycle.Event event) {
//判斷Activity(組件)生命周期狀態(tài)是否是DESTROYED 是則移除觀察者
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
//請看(4)
removeObserver(mObserver);
return;
}
//Activity(組件)生命周期改變 通知ObserverWrapper
activeStateChanged(shouldBeActive());
}
//重寫ObserverWrapper的isAttachedTo方法判斷是不是同一個(gè)生命周期
@Override
boolean isAttachedTo(LifecycleOwner owner) {
return mOwner == owner;
}
//重寫ObserverWrapper的detachObserver方法移除LifecycleBoundObserver
@Override
void detachObserver() {
mOwner.getLifecycle().removeObserver(this);
}
}
(3)LiveData的內(nèi)部抽象類ObserverWrapper源碼
// 封裝Observer的一些屬性與方法
private abstract class ObserverWrapper {
final Observer<? super T> mObserver;
boolean mActive;
int mLastVersion = START_VERSION;
ObserverWrapper(Observer<? super T> observer) {
mObserver = observer;
}
abstract boolean shouldBeActive();
//判斷是否是同一個(gè)生命周期
boolean isAttachedTo(LifecycleOwner owner) {
return false;
}
void detachObserver() {}
// 設(shè)置ObserverWrapper的mActive狀態(tài)與添加mActiveCount數(shù)量
void activeStateChanged(boolean newActive) {
//判斷Activity(組件)狀態(tài)是否改變 有沒則返回
if (newActive == mActive) {
return;
}
//設(shè)置mActive狀態(tài)
mActive = newActive;
//判斷當(dāng)前觀察者數(shù)量是否為0
boolean wasInactive = LiveData.this.mActiveCount == 0;
//當(dāng)Activity(組件)是激活狀態(tài)時(shí)+1 反之-1
LiveData.this.mActiveCount += mActive ? 1 : -1;
//當(dāng)Activity(組件)狀態(tài)屬于激活并wasInactive為ture時(shí)調(diào)用onActive()
if (wasInactive && mActive) {
//也就是當(dāng)觀察者的數(shù)量從0變?yōu)?時(shí)調(diào)用
onActive();
}
//當(dāng)活動(dòng)觀察者的數(shù)量從1變?yōu)?時(shí)調(diào)用
if (LiveData.this.mActiveCount == 0 && !mActive) {
onInactive();
}
// 當(dāng)Activity(組件)屬于激活是調(diào)用dispatchingValue
if (mActive) {
//查看(6)分析
dispatchingValue(this);
}
}
}
(4)LiveData類的removeObserver方法
//從觀察者列表中刪除給定的觀察者
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
//請看(5)
assertMainThread("removeObserver");
//從mObservers列表中移除observer
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
return;
}
//移除Observer并通知相關(guān)屬性記錄更改
removed.detachObserver();
removed.activeStateChanged(false);
}
(5)LiveData類的assertMainThread方法
//用于判斷是否在主線程 不是則拋出異常IllegalStateException
private static void assertMainThread(String methodName) {
if (!ArchTaskExecutor.getInstance().isMainThread()) {
throw new IllegalStateException("Cannot invoke " + methodName + " on a background"
+ " thread");
}
}
(6)LiveData類的dispatchingValue方法分析
// 經(jīng)過一系列的判斷 最后調(diào)用considerNotify方法更新數(shù)據(jù)
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
//判斷值是否在分發(fā)當(dāng)中
if (mDispatchingValue) {
mDispatchInvalidated = true;
return;
}
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
if (initiator != null) {
//請看(7)
considerNotify(initiator);
initiator = null;
} else {
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
//請看(7)
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
mDispatchingValue = false;
}
}
(7)LiveData類的considerNotify方法分析
//當(dāng)Activity(組件)屬于激活狀態(tài)時(shí) 把數(shù)據(jù)傳給observer的onChanged方法
private void considerNotify(ObserverWrapper observer) {
// Activity(組件)狀態(tài)屬于非激活狀態(tài)時(shí) 返回
if (!observer.mActive) {
return;
}
// 繼續(xù)檢測observer屬于非激活狀態(tài)時(shí)設(shè)置activeStateChanged為false 并返回
if (!observer.shouldBeActive()) {
observer.activeStateChanged(false);
return;
}
// 用于攔截?cái)?shù)據(jù)沒更新,當(dāng)調(diào)用setValue時(shí)mVersion會加1,也就是沒有新數(shù)據(jù)時(shí)在這里會被攔截 不會調(diào)用到mObserver.onChanged方法
if (observer.mLastVersion > = mVersion) {
return;
}
observer.mLastVersion = mVersion;
//把數(shù)據(jù)傳給observer的onChanged方法
observer.mObserver.onChanged((T) mData);
}
總結(jié):
通過liveData.observe()方法首先判斷組件若處于激活狀態(tài),創(chuàng)建綁定生命周期與觀察者的關(guān)鍵類仲墨。
判斷該類是否存儲過勾缭,若存儲過則拋出異常。
將綁定類添加到lifecycle生命周期中目养,監(jiān)聽組件生命周期變化俩由。(具體實(shí)現(xiàn)方式看Lifecycle原理)
當(dāng)生命周期發(fā)生變化時(shí)調(diào)用觀察者的onChange()方法 ,把值傳遞過去癌蚁。中間經(jīng)過一系列判斷幻梯,具體看源碼。
3.設(shè)置值setValue源碼
//通過解析1的MutableLiveData源碼可知最后調(diào)用的是LiveData的setValue與postValue
//設(shè)置值努释。如果有活動(dòng)的觀察者碘梢,值將被發(fā)送給他們
@MainThread
protected void setValue(T value) {
assertMainThread("setValue");
mVersion++;
mData = value;
//請看(6)
dispatchingValue(null);
}
//非主線程設(shè)置值
protected void postValue(T value) {
boolean postTask;
//同步代碼塊
synchronized (mDataLock) {
postTask = mPendingData == NOT_SET;
mPendingData = value;
}
//檢測上一個(gè)任務(wù)是否執(zhí)行完畢
if (!postTask) {
return;
}
//將任務(wù)發(fā)送到主線程以設(shè)置給定的值
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
private final Runnable mPostValueRunnable = new Runnable() {
@Override
public void run() {
Object newValue;
synchronized (mDataLock) {
newValue = mPendingData;
mPendingData = NOT_SET;
}
//最后也是通過setValue方法進(jìn)行通知
setValue((T) newValue);
}
};
總結(jié):
- postValue方法主要是將任務(wù)切換到主線程并調(diào)用了setValue方通知觀察者。
- 而setValue方法則是調(diào)用了dispatchingValue()將值分發(fā)給Observer.onChanged方法伐蒂。
四痘系、內(nèi)容推薦
- 《CSDN》《簡書》
- 《Android Jetpack架構(gòu)組件之Lifecycle源碼分析》
- 《Android Jetpack架構(gòu)組件之Lifecycle入門》
- 《Android Espresso入門到自動(dòng)搞定》
- 《Android ButterKnife入門到放棄》
五、項(xiàng)目參考
本文相關(guān)代碼及Demo都放在下面項(xiàng)目中饿自。有興趣可體驗(yàn)一把
若您發(fā)現(xiàn)文章中存在錯(cuò)誤或不足的地方汰翠,希望您能指出龄坪!