本文章已授權(quán)微信公眾號郭霖(guolin_blog)轉(zhuǎn)載呈宇。
本文章主要是對LiveData進行源碼分析盟蚣,建議對著示例代碼閱讀文章铜异,示例代碼如下:
本文章使用的是Android SDK 29的源碼分析艰垂。
定義
LiveData是一種可觀察的數(shù)據(jù)存儲器類蹲蒲,它具有生命周期感知能力,遵循應(yīng)用組件(例如:Activity索赏、Fragment盼玄、Service(可以使用LifecycleService,它是實現(xiàn)了LifecycleOwner接口的Service))的生命周期潜腻,這種感知能力確保LiveData僅更新處于活躍生命周期狀態(tài)的應(yīng)用組件觀察者埃儿。
如果觀察者(由Observer類表示)的生命周期處于STARTED或者RESUMED狀態(tài),那么LiveData會認為該觀察者處于活躍狀態(tài)砾赔,就會將更新通知它,而那些觀察LiveData對象而注冊的非活躍觀察者不會收到更改通知青灼。
應(yīng)用組件都實現(xiàn)了LifecycleOwner接口暴心,有了這種關(guān)系后,當(dāng)相應(yīng)的Lifecycle對象的狀態(tài)變?yōu)?strong>DESTROYED時杂拨,就會移除這些觀察者专普。
使用LiveData的優(yōu)勢:
-
確保界面符合數(shù)據(jù)狀態(tài)
LiveData遵循觀察者模式,當(dāng)生命周期狀態(tài)發(fā)生變化的時候弹沽,它就會去通知Observer對象檀夹,然后去更新界面筋粗。
-
不會發(fā)生內(nèi)存泄露
當(dāng)應(yīng)用組件的生命周期處于DESTROYED狀態(tài)時,就會移除這些觀察者炸渡,使其不再持有應(yīng)用組件的引用娜亿。
-
不會因Activity停止而導(dǎo)致崩潰
如果觀察者的生命周期處于非活躍狀態(tài)(例如:返回棧中的Actvity),則它不會接受任何LiveData的事件蚌堵。
-
不再需要手動處理生命周期
界面組件只是觀察相關(guān)數(shù)據(jù)买决,不會停止或恢復(fù)觀察,LiveData將自動管理所有這些操作吼畏,因為它在觀察的時候可以感知相關(guān)的生命周期狀態(tài)變化督赤。
-
數(shù)據(jù)始終保持最新狀態(tài)
如果生命周期變?yōu)?strong>非活躍狀態(tài),它會在再次變?yōu)?strong>活躍狀態(tài)時接收最新的數(shù)據(jù)泻蚊,例如:曾經(jīng)在后臺的Activity會在返回前臺后立即接收最新的數(shù)據(jù)躲舌。
-
適當(dāng)?shù)呐渲酶?/strong>
如果由于配置更改(例如:設(shè)備旋轉(zhuǎn))而重新創(chuàng)建了Activity或者Fragment,它會立即接收到最新的數(shù)據(jù)性雄。
-
共享資源
我們可以使用單例模式繼承LiveData以封裝相關(guān)業(yè)務(wù)邏輯没卸,以便在應(yīng)用中共享它們。
使用LiveData
使用步驟如下:
- 通常是在ViewModel中創(chuàng)建LiveData實例以存儲某種類型的數(shù)據(jù)毅贮。
- 創(chuàng)建Observer對象办悟,并且實現(xiàn)它的onChanged方法,這個方法可以控制當(dāng)LiveData對象存儲的數(shù)據(jù)發(fā)生更改時要處理什么滩褥。
- 在大多數(shù)情況下病蛉,會在應(yīng)用組件的onCreate方法觀察LiveData對象,調(diào)用LiveData對象的observer方法瑰煎,有兩個參數(shù)铺然,第一個參數(shù)是LifecycleOwner,它是一個接口酒甸,Activity魄健、Fragment、LifecycleService都實現(xiàn)了這個接口插勤,第二個參數(shù)是第二步創(chuàng)建的Observer對象沽瘦,這樣就可以使Observer對象訂閱LiveData對象,以使其收到有關(guān)更改的通知农尖。
注意:請確保用于更新界面的LiveData對象存儲在ViewModel對象中析恋,而不是將其存儲在Activity或者Fragment中,原因如下:
- 避免Activity或者Fragment過于龐大盛卡,因為這些界面控制器只負責(zé)顯示數(shù)據(jù)助隧,不負責(zé)存儲數(shù)據(jù)狀態(tài)。
- 將LiveData實例與Activity和Fragment分離開滑沧,可以使它在配置更改后繼續(xù)存在并村。
示例代碼
項目添加如下依賴:
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0-alpha02'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.0'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0-rc03'
由于我這邊用到了DataBinding巍实,所以加上如下代碼:
dataBinding {
enabled = true
}
項目結(jié)構(gòu)如下圖:
定義MainViewModel,并且繼承ViewModel哩牍,在該類中創(chuàng)建兩個MutableLiveData棚潦,firstContent是為了演示在主線程更新LiveData對象,secondContent是為了演示在工作線程更新LiveData對象姐叁,代碼如下:
/**
* Created by TanJiaJun on 2019-12-22.
*/
class MainViewModel : ViewModel() {
private val _firstContent = MutableLiveData<String>().apply {
value = "第一個文本"
}
val firstContent: LiveData<String> = _firstContent
private val _secondContent = MutableLiveData<String>().apply {
value = "第二個文本"
}
val secondContent: LiveData<String> = _secondContent
// 在主線程更新LiveData對象瓦盛,調(diào)用了MutableLiveData的setValue方法,下面會分析
fun changeFirstContent(text: String) {
_firstContent.value = text
}
// 在工作線程更新LiveData對象外潜,調(diào)用了MutableLiveData的postValue方法原环,下面會分析
fun changeSecondContent(text: String) =
viewModelScope.launch {
withContext(Dispatchers.Default) {
_secondContent.postValue(text)
}
}
}
定義FirstFragment,代碼如下:
/**
* Created by TanJiaJun on 2019-12-22.
*/
class FirstFragment : Fragment(), FirstHandlers {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? =
DataBindingUtil.inflate<FragmentFirstBinding>(
inflater,
R.layout.fragment_first,
container,
false
)
.also { binding ->
// 調(diào)用了setLifecycleOwner方法处窥,下面會分析
binding.lifecycleOwner = this
// 使MainViewModel與視圖綁定
binding.viewModel = activity?.let {
ViewModelProviders.of(it)[MainViewModel::class.java]
}
binding.handlers = this
}
.root
// 點擊Button導(dǎo)航到SecondFragment
override fun onNavigateToSecondFragmentClick(view: View) {
(activity as MainActivity).addFragment(SecondFragment(), FRAGMENT_TAG_SECOND)
}
}
interface FirstHandlers {
fun onNavigateToSecondFragmentClick(view: View)
}
定義SecondFragment嘱吗,代碼如下:
/**
* Created by TanJiaJun on 2019-12-22.
*/
class SecondFragment : Fragment(), SecondHandlers {
private var viewModel: MainViewModel? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = activity?.let { ViewModelProviders.of(it)[MainViewModel::class.java] }
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? =
DataBindingUtil.inflate<FragmentSecondBinding>(
inflater,
R.layout.fragment_second,
container,
false
)
.also {
it.handlers = this
}
.root
// 點擊第一個Button調(diào)用MainViewModel中的changeFirstContent方法,使FirstFragment中的第一個TextView的文本從”第一個文本“變成”第一個文本已改變“
override fun onChangeFirstContentClick(view: View) {
viewModel?.changeFirstContent(getString(R.string.first_content_changed))
}
// 點擊第二個Button調(diào)用MainViewModel中的changeSecondContent方法滔驾,使FirstFragment中的第二個TextView的文本從”第二個文本“變?yōu)椤钡诙€文本已改變“
override fun onChangeSecondContentClick(view: View) {
viewModel?.changeSecondContent(getString(R.string.second_content_changed))
}
}
interface SecondHandlers {
fun onChangeFirstContentClick(view: View)
fun onChangeSecondContentClick(view: View)
}
由于我這里還同時用到了DataBinding谒麦、ViewModel、Kotlin協(xié)程哆致,所以我會在下面先按照官方文檔的寫法進行源碼分析绕德。
源碼分析
LiveData是一個抽象類,我們常用的主要用到MutableLiveData和MediatorLiveData這兩個子類摊阀,我們先看下LiveData的結(jié)構(gòu)圖:
我們看下幾個常用的方法耻蛇,先看下observer方法,observer方法是用于在指定的LifecycleOwner內(nèi)將指定的觀察者添加到觀察列表中胞此,代碼如下:
// LiveData.java
// 創(chuàng)建key為Observer臣咖,value為ObserverWrapper的Map
private SafeIterableMap<Observer<? super T>, ObserverWrapper> mObservers =
new SafeIterableMap<>();
@MainThread
public void observe(@NonNull LifecycleOwner owner, @NonNull Observer<? super T> observer) {
// 檢查是否在主線程,如果不在主線程就會拋出異常
assertMainThread("observe");
// 判斷LifecycleOwner是否處于DESTROYED狀態(tài)
if (owner.getLifecycle().getCurrentState() == DESTROYED) {
// 如果是就return漱牵,不再分發(fā)
return;
}
// 創(chuàng)建LifecycleBoundObserver夺蛇,對傳入的LifecycleOwner和Observer進行包裝,下面會分析這個類
LifecycleBoundObserver wrapper = new LifecycleBoundObserver(owner, observer);
// 把LifecycleBoundObserver存儲到SafeIterableMap酣胀,key為Observer刁赦,value為ObserverWrapper,如果是第一次存儲這個Observer闻镶,就會返回null
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
// 第一個條件是判斷是否第一次存儲這個Observer甚脉,第二個條件是判斷這個Observer是否已經(jīng)附在到LifecycleOwner
if (existing != null && !existing.isAttachedTo(owner)) {
// 如果不是第一次存儲這個Observer,而且已經(jīng)附在到LifecycleOwner儒溉,拋出“不能添加附加到不同的生命周期宦焦,但是是相同的Observer
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
// 再次判斷是否第一次存儲這個Observer
if (existing != null) {
// 如果不是第一次存儲這個Observer就return
return;
}
// 調(diào)用Lifecycle的addObserver方法
owner.getLifecycle().addObserver(wrapper);
}
SafeIterableMap是個Map发钝,它實際上是個LinkedList顿涣,并且支持在迭代期間修改波闹,但是不是線程安全,LiveData用它來存儲LifecycleBoundObserver涛碑。
Lifecycle是一個抽象類精堕,它的唯一子類是LifecycleRegistry,我們看下它的addObserver方法蒲障,代碼如下:
// LifecycleRegistry.java
// 創(chuàng)建key為LifecycleObserver歹篓,value為ObserverWithState的FastSafeIterableMap
private FastSafeIterableMap<LifecycleObserver, ObserverWithState> mObserverMap =
new FastSafeIterableMap<>();
// 擁有此生命周期的提供者,在LifecycleOwner上只保留弱引用揉阎,所以如果有人泄露了Lifecycle對象庄撮,它們不會泄露整個Activity或者Fragment,但是這樣做也會泄露所有Listener對象毙籽,因為在所有Listener對象上保持著強引用
private final WeakReference<LifecycleOwner> mLifecycleOwner;
public LifecycleRegistry(@NonNull LifecycleOwner provider) {
mLifecycleOwner = new WeakReference<>(provider);
mState = INITIALIZED;
}
@Override
public void addObserver(@NonNull LifecycleObserver observer) {
State initialState = mState == DESTROYED ? DESTROYED : INITIALIZED;
// 將LifecycleObserver(我們傳入的是LifecycleBoundObserver)和State包裝成ObserverWithState
ObserverWithState statefulObserver = new ObserverWithState(observer, initialState);
// 把ObserverWithState存儲到FastSafeIterableMap洞斯,key為LifecycleBoundObserver,value為ObserverWithState坑赡,如果是第一次存儲這個ObserverWithState,就會返回null
ObserverWithState previous = mObserverMap.putIfAbsent(observer, statefulObserver);
// 判斷是否第一次存儲這個ObserverWithState
if (previous != null) {
// 如果不是第一次存儲這個ObserverWithState就return
return;
}
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
// 判斷LifecycleOwner是不是null
if (lifecycleOwner == null) {
// 如果是null的話,應(yīng)該立刻被銷毀赘那,快速回退
return;
}
boolean isReentrance = mAddingObserverCounter != 0 || mHandlingEvent;
State targetState = calculateTargetState(observer);
mAddingObserverCounter++;
while ((statefulObserver.mState.compareTo(targetState) < 0
&& mObserverMap.contains(observer))) {
pushParentState(statefulObserver.mState);
statefulObserver.dispatchEvent(lifecycleOwner, upEvent(statefulObserver.mState));
popParentState();
// mState或者subling可能被重新計算
targetState = calculateTargetState(observer);
}
// 判斷是不是在堆棧的頂層
if (!isReentrance) {
// 如果是在堆棧的頂層就執(zhí)行同步
sync();
}
mAddingObserverCounter--;
}
如果是在堆棧的頂層评雌,就會調(diào)用sync方法,因此也不會在重入的時候調(diào)用這個方法螟加,我們看下這個方法徘溢,代碼如下:
// LifecycleRegistry.java
private void sync() {
LifecycleOwner lifecycleOwner = mLifecycleOwner.get();
// 判斷LifecycleOwner是不是null
if (lifecycleOwner == null) {
// 如果是null的話,拋出異常仰迁,證明這個LifecycleRegistry的LifecycleOwner已經(jīng)被垃圾回收了甸昏,改變生命周期太遲了
throw new IllegalStateException("LifecycleOwner of this LifecycleRegistry is already"
+ "garbage collected. It is too late to change lifecycle state.");
}
while (!isSynced()) {
mNewEventOccurred = false;
// 不需要檢查eldest是不是null,因為isSynced已經(jīng)幫我們判斷了
if (mState.compareTo(mObserverMap.eldest().getValue().mState) < 0) {
// 如果ObserverWithState的state小于當(dāng)前的state徐许,就會倒序遍歷改變狀態(tài)同時通知觀察者
backwardPass(lifecycleOwner);
}
Entry<LifecycleObserver, ObserverWithState> newest = mObserverMap.newest();
if (!mNewEventOccurred && newest != null
&& mState.compareTo(newest.getValue().mState) > 0) {
// 如果ObserverWithState的state大于當(dāng)前的state施蜜,就會正序遍歷改變狀態(tài)同時通知觀察者
forwardPass(lifecycleOwner);
}
}
mNewEventOccurred = false;
}
我們看下forwardPass方法和backwardPass方法,代碼如下:
// LifecycleRegistry.java
// 正序遍歷改變狀態(tài)同時通知觀察者
private void forwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> ascendingIterator =
mObserverMap.iteratorWithAdditions();
// 正序遍歷mObserverMap
while (ascendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = ascendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) < 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
pushParentState(observer.mState);
// 調(diào)用ObserverWithState的dispatchEvent方法
observer.dispatchEvent(lifecycleOwner, upEvent(observer.mState));
popParentState();
}
}
}
// 倒序遍歷改變狀態(tài)同時通知觀察者
private void backwardPass(LifecycleOwner lifecycleOwner) {
Iterator<Entry<LifecycleObserver, ObserverWithState>> descendingIterator =
mObserverMap.descendingIterator();
// 倒序遍歷mObserverMap
while (descendingIterator.hasNext() && !mNewEventOccurred) {
Entry<LifecycleObserver, ObserverWithState> entry = descendingIterator.next();
ObserverWithState observer = entry.getValue();
while ((observer.mState.compareTo(mState) > 0 && !mNewEventOccurred
&& mObserverMap.contains(entry.getKey()))) {
Event event = downEvent(observer.mState);
pushParentState(getStateAfter(event));
// 調(diào)用ObserverWithState的dispatchEvent方法
observer.dispatchEvent(lifecycleOwner, event);
popParentState();
}
}
}
ObserverWithState是LifecycleRegistry的靜態(tài)內(nèi)部類雌隅,我們看下ObserverWithState的dispatchEvent方法翻默,代碼如下:
// LifecycleRegistry.java
static class ObserverWithState {
State mState;
LifecycleEventObserver mLifecycleObserver;
ObserverWithState(LifecycleObserver observer, State initialState) {
// mLifecycleObserver為LifecycleBoundObserver
mLifecycleObserver = Lifecycling.lifecycleEventObserver(observer);
mState = initialState;
}
void dispatchEvent(LifecycleOwner owner, Event event) {
State newState = getStateAfter(event);
mState = min(mState, newState);
// 調(diào)用LifecycleBoundObserver的onStateChanged方法
mLifecycleObserver.onStateChanged(owner, event);
mState = newState;
}
}
LifecycleBoundObserver為LiveData的內(nèi)部類,我們看下onStateChanged方法恰起,代碼如下:
// LiveData.java
// 這個方法判斷Lifecycle的狀態(tài)的值是否大于或等于STARTED狀態(tài)的值修械,從而判斷是否是活躍狀態(tài)
@Override
boolean shouldBeActive() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
// 判斷Lifecycle是否為DESTROYED狀態(tài)
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
// 如果Lifecycle是DESTROYED狀態(tài),移除觀察者检盼,并且return肯污,下面會對removeObserver方法分析
removeObserver(mObserver);
return;
}
// 如果Lifecycle不是DESTROYED狀態(tài),調(diào)用activeStateChanged方法,并且傳入shouldBeActive方法得到的布爾值
activeStateChanged(shouldBeActive());
}
State是個枚舉蹦渣,代碼如下:
@SuppressWarnings("WeakerAccess")
public enum State {
DESTROYED,
INITIALIZED,
CREATED,
STARTED,
RESUMED;
// 判斷當(dāng)前state的值是否大于或等于傳入的state的值
public boolean isAtLeast(@NonNull State state) {
return compareTo(state) >= 0;
}
}
我們可以看到哄芜,大于或等于STARTED的值就只有STARTED和RESUMED這兩個值了,也就是說這個方法是判斷是否為活躍狀態(tài)柬唯。
activeStateChanged方法代碼如下:
// LiveData.java
void activeStateChanged(boolean newActive) {
// 判斷狀態(tài)是否發(fā)生變化
if (newActive == mActive) {
// 如果沒有發(fā)生變化就return
return;
}
// 如果有發(fā)生變化认臊,立刻設(shè)置狀態(tài),這樣就不會向不活躍的觀察者發(fā)送內(nèi)容
mActive = newActive;
boolean wasInactive = LiveData.this.mActiveCount == 0;
// 如果當(dāng)前狀態(tài)是活躍狀態(tài)就會加1锄奢,否則就會減1
LiveData.this.mActiveCount += mActive ? 1 : -1;
if (wasInactive && mActive) {
// 如果mActiveCount從0變成1失晴,同時當(dāng)前狀態(tài)屬于活躍狀態(tài),就會調(diào)用onActive方法
onActive();
}
if (LiveData.this.mActiveCount == 0 && !mActive) {
// 如果mActiveCount從1變成0拘央,同時當(dāng)前狀態(tài)屬于不活躍狀態(tài)涂屁,就會調(diào)用onInactive
onInactive();
}
if (mActive) {
// 如果當(dāng)前狀態(tài)是活躍狀態(tài),調(diào)用dispatchingValue灰伟,并且傳入LifecycleBoundObserver
dispatchingValue(this);
}
}
我們看下dispatchingValue方法胯陋,代碼如下:
// LiveData.java
@SuppressWarnings("WeakerAccess") /* synthetic access */
void dispatchingValue(@Nullable ObserverWrapper initiator) {
// 判斷是否正在分發(fā)
if (mDispatchingValue) {
// 如果正在分發(fā),將mDispatchInvalidated設(shè)為true袱箱,也就是設(shè)為分發(fā)無效遏乔,并且return
mDispatchInvalidated = true;
return;
}
// 正在分發(fā)
mDispatchingValue = true;
do {
mDispatchInvalidated = false;
// 判斷initiator是否為null,根據(jù)上面的代碼可知发笔,這里不為null盟萨,注意一下為null的邏輯,下面在說setValue了讨、postValue捻激、getValue的時候會涉及到
if (initiator != null) {
// 如果initiator不為null就會調(diào)用considerNotify方法,傳入LifecycleBoundObserver
considerNotify(initiator);
initiator = null;
} else {
// 如果initiator為null就會遍歷mObservers
for (Iterator<Map.Entry<Observer<? super T>, ObserverWrapper>> iterator =
mObservers.iteratorWithAdditions(); iterator.hasNext(); ) {
// 調(diào)用considerNotify方法
considerNotify(iterator.next().getValue());
if (mDispatchInvalidated) {
break;
}
}
}
} while (mDispatchInvalidated);
// 分發(fā)完畢
mDispatchingValue = false;
}
mDispatchingValue和mDispatchInvalidated這兩個變量是為了防止重復(fù)分發(fā)相同的內(nèi)容前计。
considerNotify方法代碼如下:
// LiveData.java
@SuppressWarnings("unchecked")
private void considerNotify(ObserverWrapper observer) {
// 判斷是否為活躍狀態(tài)
if (!observer.mActive) {
// 如果不是活躍狀態(tài)就return
return;
}
// 在分發(fā)之前再檢查下最新的狀態(tài)是否為活躍狀態(tài)胞谭,防止出現(xiàn)改變了狀態(tài),但是我們還沒收到事件這種情況
if (!observer.shouldBeActive()) {
// 如果不是活躍狀態(tài)就通知不再分發(fā)
observer.activeStateChanged(false);
return;
}
// 判斷是否為最新的數(shù)據(jù)
if (observer.mLastVersion >= mVersion) {
// 如果是最新的數(shù)據(jù)就不再分發(fā)
return;
}
// 將版本設(shè)為最新的版本
observer.mLastVersion = mVersion;
// 調(diào)用onChanged方法
observer.mObserver.onChanged((T) mData);
}
onChanged方法的代碼如下:
// Observer.java
public interface Observer<T> {
void onChanged(T t);
}
onChanged方法就是我們需要實現(xiàn)的方法男杈,我們可以在這個方法實現(xiàn)數(shù)據(jù)發(fā)生變化的時候要執(zhí)行的邏輯丈屹。
大家還記得sync這個方法嗎?如果忘記了伶棒,可以再往上面看下旺垒,這個sync方法也會被moveToState方法調(diào)用,代碼如下:
// LifecycleRegistry.java
private void moveToState(State next) {
if (mState == next) {
return;
}
mState = next;
// 判斷是否在同步或者是否在添加觀察者
if (mHandlingEvent || mAddingObserverCounter != 0) {
mNewEventOccurred = true;
// we will figure out what to do on upper level.
// 如果正在同步或者正在添加觀察者就return
return;
}
mHandlingEvent = true;
// 調(diào)用sync方法
sync();
mHandlingEvent = false;
}
moveToState方法也會被handleLifecycleEvent方法調(diào)用肤无,這個方法作用是改變生命周期狀態(tài)先蒋,同時通知觀察者,如果現(xiàn)在的生命周期狀態(tài)和最近一次調(diào)用這個方法的生命周期狀態(tài)一樣的話宛渐,調(diào)用這個方法是沒有影響的竞漾,代碼如下:
// LifecycleRegistry.java
public void handleLifecycleEvent(@NonNull Lifecycle.Event event) {
State next = getStateAfter(event);
moveToState(next);
}
那LifecycleRegistry對象是什么時候創(chuàng)建呢眯搭?有什么作用呢?我們的示例代碼中MainActivity是繼承AppCompatActivity的业岁,AppCompatActivity繼承FragmentActivity坦仍,FragmentActivity繼承androidx.activity.ComponentActivity,我們看下androidx.activity.ComponentActivity的代碼:
// androidx.activity.ComponentActivity.java
// 創(chuàng)建LifecycleRegistry對象
private final LifecycleRegistry mLifecycleRegistry = new LifecycleRegistry(this);
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSavedStateRegistryController.performRestore(savedInstanceState);
// 注入ReportFragment
ReportFragment.injectIfNeededIn(this);
if (mContentLayoutId != 0) {
setContentView(mContentLayoutId);
}
}
我們看下ReportFragment部分代碼叨襟,代碼如下:
// ReportFragment.java
private static final String REPORT_FRAGMENT_TAG = "androidx.lifecycle"
+ ".LifecycleDispatcher.report_fragment_tag";
public static void injectIfNeededIn(Activity activity) {
// ProcessLifecycleOwner應(yīng)該總是要正確工作,有一些Activity可能不繼承support lib的FragmentActivity幔荒,所以使用framework的Fragment
android.app.FragmentManager manager = activity.getFragmentManager();
if (manager.findFragmentByTag(REPORT_FRAGMENT_TAG) == null) {
manager.beginTransaction().add(new ReportFragment(), REPORT_FRAGMENT_TAG).commit();
// Hopefully, we are the first to make a transaction.
manager.executePendingTransactions();
}
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
dispatchCreate(mProcessListener);
// 調(diào)用了dispatch方法糊闽,傳入Lifecycle.Event.ON_CREATE
dispatch(Lifecycle.Event.ON_CREATE);
}
@Override
public void onStart() {
super.onStart();
dispatchStart(mProcessListener);
// 調(diào)用dispatch方法,傳入Lifecycle.Event.ON_START
dispatch(Lifecycle.Event.ON_START);
}
@Override
public void onResume() {
super.onResume();
dispatchResume(mProcessListener);
// 調(diào)用dispatch方法爹梁,傳入Lifecycle.Event.ON_RESUME
dispatch(Lifecycle.Event.ON_RESUME);
}
@Override
public void onPause() {
super.onPause();
// 調(diào)用dispatch方法右犹,傳入Lifecycle.Event.ON_PAUSE
dispatch(Lifecycle.Event.ON_PAUSE);
}
@Override
public void onStop() {
super.onStop();
// 調(diào)用dispatch方法,傳入Lifecycle.Event.ON_STOP
dispatch(Lifecycle.Event.ON_STOP);
}
@Override
public void onDestroy() {
super.onDestroy();
// 調(diào)用dispatch方法姚垃,傳入Lifecycle.Event.ON_DESTROY
dispatch(Lifecycle.Event.ON_DESTROY);
// 保證不泄露某個Activity的引用
mProcessListener = null;
}
private void dispatch(Lifecycle.Event event) {
Activity activity = getActivity();
// 判斷Activity是否實現(xiàn)LifecycleRegistryOwner接口
if (activity instanceof LifecycleRegistryOwner) {
// 調(diào)用handleLifecycleEvent方法
((LifecycleRegistryOwner) activity).getLifecycle().handleLifecycleEvent(event);
return;
}
// 判斷Activity是否實現(xiàn)LifecycleOwner接口
if (activity instanceof LifecycleOwner) {
Lifecycle lifecycle = ((LifecycleOwner) activity).getLifecycle();
// 判斷Lifecycle是否是LifecycleRegistry的子類
if (lifecycle instanceof LifecycleRegistry) {
// 調(diào)用handleLifecycleEvent方法
((LifecycleRegistry) lifecycle).handleLifecycleEvent(event);
}
}
}
ReportFragment的作用是為了感知Activity的生命周期念链,每當(dāng)Activity的生命周期發(fā)生變化的時候,就會調(diào)用LifecycleRegistry的handleLifecycleEvent方法积糯,然后就會調(diào)用moveToState方法掂墓,最后就會調(diào)用sync方法,從而讓LiveData能感知Activity的生命周期看成,其實這也是Android Jetpack的另外一個很重要的組件Lifecycle的原理君编,同樣我們也看下Fragment的代碼:
// Fragment.java
LifecycleRegistry mLifecycleRegistry;
@Nullable FragmentViewLifecycleOwner mViewLifecycleOwner;
MutableLiveData<LifecycleOwner> mViewLifecycleOwnerLiveData = new MutableLiveData<>();
private void initLifecycle() {
// 創(chuàng)建LifecycleRegistry對象
mLifecycleRegistry = new LifecycleRegistry(this);
mSavedStateRegistryController = SavedStateRegistryController.create(this);
// 判斷當(dāng)前Android版本是否大于4.4
if (Build.VERSION.SDK_INT >= 19) {
mLifecycleRegistry.addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
// 判斷當(dāng)前事件是否是ON_STOP
if (event == Lifecycle.Event.ON_STOP) {
// 判斷View是否為null
if (mView != null) {
// 如果不是空的話,取消之前發(fā)布到事件隊列的任何延遲的高級別輸入事件
mView.cancelPendingInputEvents();
}
}
}
});
}
}
void performCreate(Bundle savedInstanceState) {
// 省略部分代碼
// 調(diào)用handleLifecycleEvent川慌,傳入Lifecycle.Event.ON_CREATE
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
mPerformedCreateView = true;
// 創(chuàng)建Fragment的View的LifecycleOwner
mViewLifecycleOwner = new FragmentViewLifecycleOwner();
mView = onCreateView(inflater, container, savedInstanceState);
// 判斷View是否為null
if (mView != null) {
// 創(chuàng)建Fragment的View的Lifecycle
mViewLifecycleOwner.initialize();
// 然后通知新的LifecycleOwner的一些觀察者
mViewLifecycleOwnerLiveData.setValue(mViewLifecycleOwner);
} else {
// 判斷FragmentViewLifecycleOwner是否初始化
if (mViewLifecycleOwner.isInitialized()) {
// 如果View是null吃嘿,同時FragmentViewLifecycleOwner也初始化了,拋出異常
throw new IllegalStateException("Called getViewLifecycleOwner() but "
+ "onCreateView() returned null");
}
mViewLifecycleOwner = null;
}
}
void performStart() {
// 省略部分代碼
// 調(diào)用onStart方法
onStart();
// 省略部分代碼
// 調(diào)用LifecycleRegistry的handleLifecycleEvent方法梦重,傳入Lifecycle.Event.ON_START
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
// 判斷View是否為null
if (mView != null) {
// 如果View不是null兑燥,調(diào)用FragmentViewLifecycleOwner的handleLifecycleEvent,傳入Lifecycle.Event.ON_START
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
// 省略部分代碼
}
void performResume() {
// 省略部分代碼
// 調(diào)用onResume方法
onResume();
// 省略部分代碼
// 調(diào)用LifecycleRegistry的handleLifecycleEvent方法琴拧,傳入Lifecycle.Event.ON_RESUME
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
// 判斷View是否為null
if (mView != null) {
// 如果View不是null降瞳,調(diào)用FragmentViewLifecycleOwner的handleLifecycleEvent,傳入Lifecycle.Event.ON_RESUME
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
// 省略部分代碼
}
void performPause() {
// 省略部分代碼
// 判斷View是否為null
if (mView != null) {
// 如果View不是null蚓胸,調(diào)用FragmentViewLifecycleOwner的handleLifecycleEvent方法力崇,傳入Lifecycle.Event.ON_PAUSE
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
// 調(diào)用LifecycleRegistry的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_PAUSE
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
// 省略部分代碼
// 調(diào)用onPause方法
onPause();
// 省略部分代碼
}
void performStop() {
// 省略部分代碼
// 判斷View是否為null
if (mView != null) {
// 如果View不是null赢织,調(diào)用FragmentViewLifecycleOwner的handleLifecycleEvent方法亮靴,傳入Lifecycle.Event.ON_STOP
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
// 調(diào)用LifecycleRegistry的handleLifecycleEvent方法,傳入Lifecycle.Event.ON_STOP
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
// 省略部分代碼
// 調(diào)用onStop方法
onStop();
// 省略部分代碼
}
void performDestroyView() {
// 判斷View是否為null
if (mView != null) {
// 如果View不是null于置,調(diào)用FragmentViewLifecycleOwner的handleLifecycleEvent方法茧吊,傳入Lifecycle.Event.ON_DESTROY
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
// 省略部分代碼
onDestroyView();
// 省略部分代碼
}
void performDestroy() {
// 省略部分代碼
// 調(diào)用LifecycleRegistry的handleLifecycleEvent方法贞岭,傳入Lifecycle.Event.ON_DESTROY
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
// 省略部分代碼
// 調(diào)用onDestroy方法
onDestroy();
// 省略部分代碼
}
FragmentViewLifecycleOwner表示的是Fragment的View的生命周期,在大多數(shù)情況下搓侄,這反映了Fragment本身的生命周期瞄桨,但是Fragment的生命周期肯定會比它的View的生命周期要長。
同理讶踪,每當(dāng)Fragment的生命周期發(fā)生變化的時候芯侥,就會調(diào)用LifecycleRegistry的handleLifecycleEvent方法和FragmentViewLifecycleOwner的handleLifecycleEvent方法,然后就會調(diào)用moveToState方法乳讥,最后就會調(diào)用sync方法柱查,從而讓LiveData能感知Fragment的生命周期。
然后我們再看下removeObserver方法云石,代碼如下:
// LiveData.java
// 這個方法要在主線程調(diào)用
@MainThread
public void removeObserver(@NonNull final Observer<? super T> observer) {
// 判斷是否在主線程
assertMainThread("removeObserver");
ObserverWrapper removed = mObservers.remove(observer);
if (removed == null) {
// 如果是null的話就return
return;
}
// 調(diào)用LifecycleBoundObserver的detachObserver方法
removed.detachObserver();
// 調(diào)用LifecycleBoundObserver的activeStateChanged方法唉工,并且傳入false,這個方法在上面也分析過了汹忠,這里不再贅述
removed.activeStateChanged(false);
}
detachObserver方法的代碼如下:
// LiveData.java
@Override
void detachObserver() {
// 調(diào)用LifecycleRegistry的removeObserver方法
mOwner.getLifecycle().removeObserver(this);
}
removeObserver方法的代碼如下:
// LifecycleRegistry.java
@Override
public void removeObserver(@NonNull LifecycleObserver observer) {
// 移除這個觀察者
mObserverMap.remove(observer);
}
根據(jù)上面的代碼可知淋硝,系統(tǒng)也會幫我們調(diào)用這個方法來移除觀察者,防止發(fā)生內(nèi)存泄露宽菜。
以上就是LiveData能感知生命周期的原理谣膳。
還有一個方法也比較常用:observeForever方法,我們看下它的代碼:
// LiveData.java
@MainThread
public void observeForever(@NonNull Observer<? super T> observer) {
assertMainThread("observeForever");
// 創(chuàng)建AlwaysActiveObserver
AlwaysActiveObserver wrapper = new AlwaysActiveObserver(observer);
ObserverWrapper existing = mObservers.putIfAbsent(observer, wrapper);
if (existing instanceof LiveData.LifecycleBoundObserver) {
// 如果existing是LiveData.LifecycleBoundObserver類的實例铅乡,拋出異常
throw new IllegalArgumentException("Cannot add the same observer"
+ " with different lifecycles");
}
if (existing != null) {
return;
}
// 調(diào)用AlwaysActiveObserver的activeStateChanged方法参歹,并且傳入true
wrapper.activeStateChanged(true);
}
再看下AlwaysActiveObserver的代碼:
// LiveData.java
private class AlwaysActiveObserver extends ObserverWrapper {
AlwaysActiveObserver(Observer<? super T> observer) {
super(observer);
}
// 重寫了shouldBeActive方法,并且返回true隆判,根據(jù)上面的代碼分析可知犬庇,這個方法是用來判斷是否為活躍狀態(tài),這里一直返回true侨嘀,也就是說一直保持著活躍狀態(tài)
@Override
boolean shouldBeActive() {
return true;
}
}
observeForever是用于將指定的觀察者添加到觀察列表中臭挽,類似于調(diào)用observer方法,但是給定的LifecycleOwner狀態(tài)總是為活躍狀態(tài)咬腕,這意味著觀察者將永遠接收所有的事件欢峰,所以如果要停止觀察這個LiveData,就要手動調(diào)用removeObserver方法涨共。
然后我們再看下另外三個重要的方法的源碼:setValue方法纽帖、postValue方法和getValue方法,setValue方法和postValue方法是用于給LiveData設(shè)值举反,getValue方法是用于從LiveData取值懊直,代碼如下:
// LiveData.java
final Object mDataLock = new Object();
protected void postValue(T value) {
boolean postTask;
// 同步鎖作用于mDataLock對象
synchronized (mDataLock) {
// postTask用mPendingData的值是否為NOT_SET來判斷是否需要將Runnable添加到消息隊列
postTask = mPendingData == NOT_SET;
// 將value賦值給mPendingData
mPendingData = value;
}
// 判斷是否需要將Runnable添加到消息隊列
if (!postTask) {
// 如果不需要將Runnable添加到消息隊列就return
return;
}
// 如果需要將Runnable添加到消息隊列就調(diào)用ArchTaskExecutor的postToMainThread方法,下面會對這個方法分析
ArchTaskExecutor.getInstance().postToMainThread(mPostValueRunnable);
}
// setValue必須在主線程調(diào)用
@MainThread
protected void setValue(T value) {
// 檢查是否在主線程
assertMainThread("setValue");
// mVersion自增
mVersion++;
// 將value賦值給mData
mData = value;
// 調(diào)用dispatchingValue方法
dispatchingValue(null);
}
@SuppressWarnings("unchecked")
// 值為可空的對象
@Nullable
public T getValue() {
Object data = mData;
// 判斷mData的值是否為NOT_SET
if (data != NOT_SET) {
// 如果mData的值不是NOT_SET就返回這個值
return (T) data;
}
// 如果mData的值為NOT_SET就返回null
return null;
}
我們看下postToMainThread方法火鼻,代碼如下:
// ArchTaskExecutor.java
@NonNull
private TaskExecutor mDelegate;
private ArchTaskExecutor() {
// 創(chuàng)建DefaultTaskExecutor對象
mDefaultTaskExecutor = new DefaultTaskExecutor();
// 將mDefaultTaskExecutor賦值給mDelegate
mDelegate = mDefaultTaskExecutor;
}
// 獲取ArchTaskExecutor單一實例的方法室囊,使用雙重檢查鎖定(Double Check Locking雕崩,簡稱DCL)實現(xiàn)單例
@NonNull
public static ArchTaskExecutor getInstance() {
if (sInstance != null) {
return sInstance;
}
synchronized (ArchTaskExecutor.class) {
if (sInstance == null) {
// 調(diào)用ArchTaskExecutor的構(gòu)造方法
sInstance = new ArchTaskExecutor();
}
}
return sInstance;
}
@Override
public void postToMainThread(Runnable runnable) {
// 調(diào)用DefaultTaskExecutor的postToMainThread方法
mDelegate.postToMainThread(runnable);
}
ArchTaskExecutor繼承TaskExecutor,用于執(zhí)行一些公共任務(wù)融撞,我們看到postToMainThread方法是會調(diào)用DefaultTaskExecutor的postToMainThread方法盼铁,代碼如下:
// DefaultTaskExecutor.java
@Override
public void postToMainThread(Runnable runnable) {
if (mMainHandler == null) {
synchronized (mLock) {
if (mMainHandler == null) {
// 創(chuàng)建Handler,傳入的是主線程的Looper
mMainHandler = createAsync(Looper.getMainLooper());
}
}
}
// 將runnable添加到消息隊列尝偎,runnable將在主線程中執(zhí)行
mMainHandler.post(runnable);
}
然后我們看下傳入的Runnable:mPostValueRunnable饶火,代碼如下:
// LiveData.java
final Object mDataLock = new Object();
private final Runnable mPostValueRunnable = new Runnable() {
@SuppressWarnings("unchecked")
@Override
public void run() {
Object newValue;
// 同步鎖作用于mDataLock對象
synchronized (mDataLock) {
// 將mPendingData賦值給newValue
newValue = mPendingData;
// 將mPendingData設(shè)值為NOT_SET
mPendingData = NOT_SET;
}
// 調(diào)用setValue方法,傳入newValue
setValue((T) newValue);
}
};
postValue方法最后是會調(diào)用setValue方法致扯,如果在主線程執(zhí)行已發(fā)布的任務(wù)之前多次調(diào)用這個方法肤寝,只會分發(fā)最后一個值,還有一點需要注意的是急前,假設(shè)先調(diào)用postValue方法,并且傳入a瀑构,然后調(diào)用setValue方法裆针,并且傳入b,那么會先設(shè)置為b寺晌,然后再設(shè)置為a世吨。
postValue方法最后還是會調(diào)用setValue方法,然后就會調(diào)用dispatchingValue方法呻征,并且傳入null耘婚,這個方法在上面也分析過了,這里大概說一下陆赋,如果傳入的是null的話沐祷,就會遍歷所有的觀察者,然后分發(fā)內(nèi)容攒岛,調(diào)用Observer的onChanged方法赖临,執(zhí)行我們的邏輯。
題外話
在示例代碼中灾锯,我用到了Android Jetpack的另外一個組件:DataBinding兢榨,同時調(diào)用了ViewDataBinding的setLifecycleOwner方法,代碼如下:
// FirstFragment.kt
binding.lifecycleOwner = this
我們看下對應(yīng)的源碼:
// ViewDataBinding.java
@MainThread
public void setLifecycleOwner(@Nullable LifecycleOwner lifecycleOwner) {
// 省略部分代碼
mLifecycleOwner = lifecycleOwner;
if (lifecycleOwner != null) {
if (mOnStartListener == null) {
mOnStartListener = new OnStartListener(this);
}
// 調(diào)用addObserver方法
lifecycleOwner.getLifecycle().addObserver(mOnStartListener);
}
for (WeakListener<?> weakListener : mLocalFieldObservers) {
if (weakListener != null) {
// 調(diào)用WeakListener的setLifecycleOwner方法
weakListener.setLifecycleOwner(lifecycleOwner);
}
}
}
setLifecycleOwner方法的代碼如下:
// ViewDataBinding.java
public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
mObservable.setLifecycleOwner(lifecycleOwner);
}
這里的mObservable為LiveDataListener顺饮,LiveDataListener也實現(xiàn)了Observer接口吵聪,所以我們看下相關(guān)的代碼,代碼如下:
// ViewDataBinding.java
@Override
public void setLifecycleOwner(LifecycleOwner lifecycleOwner) {
LifecycleOwner owner = (LifecycleOwner) lifecycleOwner;
LiveData<?> liveData = mListener.getTarget();
if (liveData != null) {
if (mLifecycleOwner != null) {
liveData.removeObserver(this);
}
if (lifecycleOwner != null) {
// 調(diào)用LiveData的observe方法
liveData.observe(owner, this);
}
}
mLifecycleOwner = owner;
}
// 根據(jù)上面分析可知兼雄,當(dāng)數(shù)據(jù)發(fā)生改變的時候就會調(diào)用onChanged方法
@Override
public void onChanged(@Nullable Object o) {
ViewDataBinding binder = mListener.getBinder();
if (binder != null) {
// 通知對應(yīng)的UI更新
binder.handleFieldChange(mListener.mLocalFieldId, mListener.getTarget(), 0);
}
}
setLifecycleOwner方法是用于設(shè)置LifecycleOwner吟逝,用于觀察綁定中的LiveData的更改,如果LiveData位于其中一個Binding表達式中赦肋,但是沒有設(shè)置LifecycleOwner澎办,那么LiveData將不會被觀察到嘲碱,對它的更新也不會使UI發(fā)生更新。
另外我也用到了Kotlin協(xié)程局蚀,代碼如下:
// MainViewModel.kt
fun changeSecondContent(text: String) =
viewModelScope.launch {
withContext(Dispatchers.Default) {
_secondContent.postValue(text)
}
}
viewModelScope是將協(xié)程范圍綁定到ViewModel麦锯,也就是說如果ViewModel被清除的話,這個協(xié)程范圍也會被取消琅绅,在示例代碼中扶欣,MainViewModel生命周期和MainActivity的生命周期保持一致,防止在Activity銷毀后協(xié)程還在執(zhí)行更新UI的邏輯千扶,還持有著UI控件的引用料祠,導(dǎo)致內(nèi)存泄露。
調(diào)用了withContext方法澎羞,并且傳入了Dispatchers.Default髓绽,也就是說使用Dispatchers.Default調(diào)度器調(diào)用指定的掛起塊,掛起直到完成妆绞,并且返回結(jié)果顺呕,其中Dispatchers.Default使用了共享的后臺線程池,也就是說調(diào)用postValue方法這段邏輯是在工作線程執(zhí)行的括饶,從而演示在工作線程去設(shè)置LiveData的值株茶,并且更新對應(yīng)的UI控件。
我的GitHub:TanJiaJunBeyond
Android通用框架:Android通用框架
我的掘金:譚嘉俊
我的簡書:譚嘉俊
我的CSDN:譚嘉俊