本篇文章帶讀者走一遍源碼
Fragment
的前幾個生命周期泡仗,看源碼其實有畫流程圖就不會覺得枯燥。但是寫文章我個人倒是覺得寫這種讀源碼文章挺枯燥的。堪遂。。哈哈哈 (ps:讀者您最好就是開一下IDE萌庆,看源碼跟著這里面的流程走一下溶褪,希望對你自己去看源碼會有點幫助)
Fragment生命周期
- 首先先看一下官網(wǎng)的生命周期圖。
從上面的圖可以明顯看出來
Activity
的生命周期與Fragment
是相掛鉤的践险。Activity
的生命周期是AMS
管理,Fragment
的生命周期是被所屬Activity
管理猿妈。
Fragment相關(guān)類
我們既然要看Fragment
的生命周期吹菱,而生命周期是交給Activity
管理,且跟Activity
的生命周期是相關(guān)的,那我們的切入點就可以從Activity
的生命中周期著手彭则。且本片文章所看的源碼是androidx
下的FragmentActivity
-
FragmentActivity
擁有成員對象FragmentController mFragments
-
FragmentController
擁有成員對象FragmentHostCallback mHost
-
FragmentHostCallback
擁有成員對象FragmentManagerImpl mFragmentManager
每個類對應的責任:
FragmentController
是控制類鳍刷,對外提供控制Fragment
的生命周期等方法,內(nèi)部實現(xiàn)交由FragmentHostCallback
中的FragmentManagerImpl
去最終實現(xiàn)俯抖。FragmentManagerImpl
是最終處理Fragment
所有邏輯的實現(xiàn)類输瓜。FragmentHostCallback
這個類中擁有了Activity
,Context
,FragmentManagerImpl
這幾個成員變量芬萍,在創(chuàng)建FragmentController
的時候我們需要指定一個FragmentHostCallback
實例用于指定FragmentController
的宿主尤揣。(這個不理解的話,下面第一個代碼塊中有說到)
這幾個類的關(guān)系簡化起來就是通過組合的形式柬祠,大致就是
FragmentActivity
使用一個FragmentController
管理類北戏,由它去操控最終的FragmentManagerImpl
控制Fragment
的生命周期或者其他相關(guān)的邏輯。
源碼追蹤
先切入主題漫蛔,我們看一下
FragmentActivity
類的onCreate()
public class FragmentActivity{
//mFragments的初始化
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
protected void onCreate(@Nullable Bundle savedInstanceState) {
mFragments.attachHost(null /*parent*/);
.......
mFragments.dispatchCreate();
}
//FragmentHostCallback 傳入FragmentActivity作為Fragment的宿主嗜愈。
//并提供了可以獲取到宿主信息的方法。
class HostCallbacks extends FragmentHostCallback<FragmentActivity> {
@Override
public FragmentActivity onGetHost() {
return FragmentActivity.this;
}
@Nullable
@Override
public View onFindViewById(int id) {
return FragmentActivity.this.findViewById(id);
}
}
}
上面代碼部分注釋了莽龟,我們直接看mFragments.dispatchCreate();
里面的實現(xiàn)
public class FragmentController {
private final FragmentHostCallback<?> mHost;
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
}
直接從這里面進去FragmentManagerImpl
final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 {
public void dispatchCreate() {
mStateSaved = false;
mStopped = false;
dispatchStateChange(Fragment.CREATED);//關(guān)鍵點1
}
private void dispatchStateChange(int nextState) {
...省略
moveToState(nextState, false);//關(guān)鍵點2
...省略
}
void moveToState(int newState, boolean always) {
...省略
mCurState = newState; //這里的mCurState = Fragment.CREATED
if (mActive != null) {
final int numAdded = mAdded.size();
for (int i = 0; i < numAdded; i++) {
Fragment f = mAdded.get(i);
moveFragmentToExpectedState(f);//關(guān)鍵點3
}
...省略
}
}
}
這里重點記住 傳入的狀態(tài)mCurState = Fragment.CREATED
void moveFragmentToExpectedState(Fragment f) {
...省略
int nextState = mCurState; //mCurState = Fragment.CREATED
moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false); //關(guān)鍵點1
}
這里先展示一下Fragment
狀態(tài)的對象值芝硬。后面對比用得上。
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // Fully created, not started.
static final int STARTED = 3; // Created and started, not resumed.
static final int RESUMED = 4; // Created started and resumed.
接下來就是最終控制邏輯的方法了轧房。這個方法就是控制Fragment
生命周期的邏輯實現(xiàn)拌阴,因為這個方法過于長,我截取必要部分出來奶镶。
//此時
//mState = INITIALIZING
//newState = Fragment.CREATED
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
.......省略
if (f.mState <= newState){
switch (f.mState) {//這里的case沒有break迟赃。所以會執(zhí)行所有的case。
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {
...省略
f.onAttach(mHost.getContext()); //關(guān)鍵點1
...省略
if (!f.mIsCreated) {//mIsCreated這個值賦值是在performCreate()厂镇,所以第一次為falese則符合這個條件
f.performCreate(f.mSavedFragmentState); //關(guān)鍵點2
}
}
case Fragment.CREATED:
ensureInflatedFragmentView(f);//關(guān)鍵點3
}
}
關(guān)鍵點1:調(diào)用了
Fragment
中第一個生命周期onAttach(Context context)
關(guān)鍵點2: 調(diào)用Fragment
的onCreate
方法
void performCreate(Bundle savedInstanceState) {
...省略
mState = CREATED;
mCalled = false;
onCreate(savedInstanceState);//調(diào)用Fragment的onCreate方法
mIsCreated = true;//上個代碼塊的條件值 mIsCreated的賦值在這里
...省略
}
關(guān)鍵點3: 調(diào)用Fragment
的onViewCreated
方法
void ensureInflatedFragmentView(Fragment f) {
if (f.mFromLayout && !f.mPerformedCreateView) {
f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), null, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
f.mView.setSaveFromParentEnabled(false);
if (f.mHidden) f.mView.setVisibility(View.GONE);
f.onViewCreated(f.mView, f.mSavedFragmentState);//調(diào)用Fragment的onViewCreated方法
dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
} else {
f.mInnerView = null;
}
}
}
由上面的流程下來你可以看到纤壁,當
Activity
執(zhí)行onCreate()
的時候,至少Fragment
有三個生命周期被調(diào)用到onAttach() ->onCreate()->onCreateView()
捺信。
而后的Activity onStart()
可以看一下
protected void onStart() {
super.onStart();
if (!mCreated) {
mCreated = true;
mFragments.dispatchActivityCreated();//關(guān)鍵1
}
mFragments.dispatchStart();//關(guān)鍵2
}
你可以看到上面兩個調(diào)用分別是
dispatchActivityCreated() dispatchStart()
對應Fragment
的生命期為onActivityCreate()
跟Start()
后面的就讀者自己去看一下啦 根據(jù)上面的一樣邏輯思路很容易就看懂的~
總結(jié)
其實這篇文章就是看源碼寫的文章酌媒,看源碼主要就是抓住重點,確定自己的目標要看懂什么找什么迄靠。只要確定這一點然后一邊畫代碼的流水線圖秒咨,很容易就找到代碼的流向。然后根據(jù)看懂了之后再總結(jié)一下這些類的作用掌挚,這樣寫有什么好處雨席。
最后附上一副自己在看源碼的時候畫的圖~