官網建議使用viewLifecycleOwner
在Fragment中對LiveData對象調用Observe方法的時候,如果傳遞的LifecycleOwner參數為this,也就是Fragment的時候,會受到AndroidStudio的提醒,要求使用viewLifecycleOwner:
從類型上來說,Fragment與viewLifecycleOwner的類型FragmentViewLifecycle兩者都繼承了LifecycleOwner,像之前那樣直接this,大部分情況下運行也是正常的,那么這里的Lint提醒是什么呢?
通過在官網尋找androidx.fragment:fragment的文檔,可以看到1.2.0版本更新的內容有一條:
可以知道,這肯定是有他的道理。我們來一起分析一下原因:
viewLifecycleOwner相關生命周期
找到viewLifecycleOwner相關代碼( 只看關鍵點 ):
//Fragment.java中
void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
mPerformedCreateView =true;
mViewLifecycleOwner =new FragmentViewLifecycleOwner(); //此處創建了FragmentViewLifecycleOwner
mView = onCreateView(inflater, container, savedInstanceState); //創建完成之后,調用了onCreateView()方法
... //省略無關代碼
}
//FragmentManager.java
private void destroyFragmentView(@NonNull Fragment fragment) {
fragment.performDestroyView(); //此方法中執行了onDestroyView()方法
fragment.mViewLifecycleOwner =null; //在執行完onDestroyView()方法之后,將viewLifecycleOwner置空
}
//Fragment.java
void performDestroyView() {
...
onDestroyView(); // fragment.performDestroyView()方法調用中,執行了onDestroyView()方法
...
}
可以發現mViewLifecycleOwner的賦值在onCreateView()之前,置空在onDestroyView()之后,
mViewLifecycleOwner的注釋也說明了這點:
// 這在performCreateView中初始化,在外部不可用
// This is initialized in performCreateView and unavailable outside of the
// onCreateView/onDestroyView生命周期
// onCreateView/onDestroyView lifecycle
@Nullable FragmentViewLifecycleOwner mViewLifecycleOwner;
正如類名所示,這個FragmentViewLifecycle代表的是Fragment中View的LifecycleOwner,Fragment中View的生命周期與Fragment本身并不相同。
看到這里,想必有些同學對Fragment的生命周期也半知半解,順便溫習一下:
Fragment入back stack的過程會執行onDestroyView但不執行之后的onDestroy與onDetach,而出back stack是從onCreateView開始執行,而沒有之前的onAttach與onCreate。
LiveData的observe過程
溫習了相關生命周期后,下面來看一下LiveData的observe過程。
我們知道在LiveData的observe方法內,會將參數owner與observer包裝起來,使得observer的回調受owner的生命周期的影響,只有在owner處于活躍狀態才回調observer,而活躍狀態指的是當前owner的生命周期至少為STARTED,即如下(1)處,owner與observer的包裝類中否活躍的判斷方法。
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() {
return mOwner.getLifecycle().getCurrentState().isAtLeast(STARTED);
}//(1)
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (mOwner.getLifecycle().getCurrentState() == DESTROYED) {
removeObserver(mObserver);//(2)
return;
}
activeStateChanged(shouldBeActive());
}
...
}
可是,Fragment與Fragment中的View在活躍的生命周期狀態是一致的,這里的owner使用fragment還是viewLifecycleOwner并無不同,二者只有在onCreateView到onDestroyView之外有區別。
包裝類中的onStateChanged方法會執行observer的適時移除工作,而(2)處的移除observer正是在owner處于DESTROYED時發生的。對于Fragment,狀態會在onDestroyView執行前夕,變為DESTROYED,如下所示:
//Fragment.java 也對應了上邊的內容
void performDestroyView() {
mChildFragmentManager.dispatchDestroyView();
if (mView != null) {
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
mState = CREATED;
onDestroyView();
...
}
原因
此時,一切都解釋得通了,在Fragment中對LiveData對象調用observe方法時,使用viewLifecycleOwner代替this的原因是:Fragment與Fragment中的View的生命周期并不一致,需要讓observer感知Fragment中的View的生命周期而非Fragment,因此Android專門構造了Fragment中的View的LifecycleOwner,即viewLifecycleOwner。