37、Android 記一次關於Fragment生命週期的討論。
阿新 • • 發佈:2018-11-19
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 ,其生命週期如何呼叫的呢?
話不多說直接上圖
當點選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對應的生命週期的。
有問題歡迎指正!