1. 程式人生 > >37、Android 記一次關於Fragment生命週期的討論。

37、Android 記一次關於Fragment生命週期的討論。

1、重溫基礎

1)activity 生命週期

activity 啟動: onCreat() –> onStart() –> onResume()
activity 關閉: onpause() –> onStop() –> onDestroy();

2)Fragment 生命週期

Fragment建立: onAttach() –>onCreatView() –>onViewCreated() –>onActivityCreated() –>onStart() –>onResume();

Fragment銷燬:

onPause() –>onStop() –>onDestroyView() –>onDestroy()–>onDetach()

2、Activity和Fragment 的生命週期回撥順序:

問題:
在activity中建立一個fragment ,其生命週期如何呼叫的呢?

話不多說直接上圖

onDetach

當點選home鍵時有如何進行呢?

注意:activity 和fragment生命週期的先後順序。

但是在網上很多人給出的生命週期順序是這樣的:

細心地同學發現了,activity 和fragment生命週期的順序剛好相反。很奇怪 我很快發現問題原因:

//我寫的
 @Override
    protected void onPause() {
        Log.d("activity", "---->onPause");
        super.onPause();
    }

//對方寫的
@Override
    protected void onPause() {
        super.onPause();
        Log.d("activity", "---->onPause");
    }

剛好順序呼叫反了!那怎麼知道 是先走activity 的onPause()方法 還是 先走fragment 的onPause()方法呢? 問題一度尷尬!(其實我已經知道結果了…嘿嘿)

//之後就出現了  以下的程式碼!
 @Override
    protected void onPause() {
        Log.d("activity", "---->onPause 之前");
        super.onPause();
        Log.d("activity", "---->onPause 之後");
    }

果然發現:先走avtivity的onPause()方法,之後通過呼叫才呼叫 fragment的onPause().

3、問題挖掘

通過log日誌猜測:Fragment的onPause方法是通過 super.onPause()呼叫的。
檢視原始碼

//FragmentActivity


 /**
     * Dispatch onPause() to fragments.
     */
    @Override
    protected void onPause() {
        super.onPause();
        mResumed = false;
        if (mHandler.hasMessages(MSG_RESUME_PENDING)) {
            mHandler.removeMessages(MSG_RESUME_PENDING);
            onResumeFragments();
        }
        //果然 是通過 FragmentController 分發Pause()改變fragment的狀態的
        mFragments.dispatchPause();
    }


...
//FragmentController
 /**
     * Moves all Fragments managed by the controller's FragmentManager
     * into the pause state.
     * <p>Call when Fragments should be paused.
     *
     * @see Fragment#onPause()
     */
    public void dispatchPause() {
        mHost.mFragmentManager.dispatchPause();
    }

4、結論

在activity 中建立的fragment 其生命週期是:先呼叫activity對應的生命週期,之後由activity的父類FragmentActivity通過FragmentController 更改Fragment對應的生命週期的。


有問題歡迎指正!