本篇文章带读者走一遍源码
Fragment
的前几个生命周期,看源码其实有画流程图就不会觉得枯燥。但是写文章我个人倒是觉得写这种读源码文章挺枯燥的。。。哈哈哈 (ps:读者您最好就是开一下IDE,看源码跟着这里面的流程走一下,希望对你自己去看源码会有点帮助)
Activity
的生命周期与Fragment
是相挂钩的。
Activity
的生命周期是AMS
管理,Fragment
的生命周期是被所属Activity
管理。
我们既然要看Fragment
的生命周期,而生命周期是交给Activity
管理,且跟Activity
的生命周期是相关的,那我们的切入点就可以从Activity
的生命中周期着手。且本片文章所看的源码是androidx
下的FragmentActivity
FragmentActivity
拥有成员对象FragmentController mFragments
FragmentController
拥有成员对象FragmentHostCallback mHost
FragmentHostCallback
拥有成员对象 FragmentManagerImpl mFragmentManager
每个类对应的责任:
FragmentController
是控制类,对外提供控制Fragment
的生命周期等方法,内部实现交由FragmentHostCallback
中的FragmentManagerImpl
去最终实现。FragmentManagerImpl
是最终处理Fragment
所有逻辑的实现类。FragmentHostCallback
这个类中拥有了Activity
,Context
,FragmentManagerImpl
这几个成员变量,在创建FragmentController
的时候我们需要指定一个FragmentHostCallback
实例用于指定FragmentController
的宿主。(这个不理解的话,下面第一个代码块中有说到)
这几个类的关系简化起来就是通过组合的形式,大致就是
FragmentActivity
使用一个FragmentController
管理类,由它去操控最终的FragmentManagerImpl
控制Fragment
的生命周期或者其他相关的逻辑。
先切入主题,我们看一下
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();
里面的实现
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);//关键点1 } private void dispatchStateChange(int nextState) { ...省略 moveToState(nextState, false);//关键点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);//关键点3 } ...省略 } } } 复制代码
这里重点记住 传入的状态mCurState = Fragment.CREATED
void moveFragmentToExpectedState(Fragment f) { ...省略 int nextState = mCurState; //mCurState = Fragment.CREATED moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false); //关键点1 } 复制代码
这里先展示一下Fragment
状态的对象值。后面对比用得上。
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
生命周期的逻辑实现,因为这个方法过于长,我截取必要部分出来。
//此时 //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。所以会执行所有的case。 case Fragment.INITIALIZING: if (newState > Fragment.INITIALIZING) { ...省略 f.onAttach(mHost.getContext()); //关键点1 ...省略 if (!f.mIsCreated) {//mIsCreated这个值赋值是在performCreate(),所以第一次为falese则符合这个条件 f.performCreate(f.mSavedFragmentState); //关键点2 } } case Fragment.CREATED: ensureInflatedFragmentView(f);//关键点3 } } 复制代码
关键点1:调用了
Fragment
中第一个生命周期onAttach(Context context)
关键点2: 调用Fragment
的onCreate
方法
void performCreate(Bundle savedInstanceState) { ...省略 mState = CREATED; mCalled = false; onCreate(savedInstanceState);//调用Fragment的onCreate方法 mIsCreated = true;//上个代码块的条件值 mIsCreated的赋值在这里 ...省略 } 复制代码
关键点3: 调用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);//调用Fragment的onViewCreated方法 dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false); } else { f.mInnerView = null; } } } 复制代码
由上面的流程下来你可以看到,当
Activity
执行onCreate()
的时候,至少Fragment
有三个生命周期被调用到onAttach() ->onCreate()->onCreateView()
。 而后的Activity onStart()
可以看一下
protected void onStart() { super.onStart(); if (!mCreated) { mCreated = true; mFragments.dispatchActivityCreated();//关键1 } mFragments.dispatchStart();//关键2 } 复制代码
你可以看到上面两个调用分别是
dispatchActivityCreated() dispatchStart()
对应Fragment
的生命期为onActivityCreate()
跟Start()
后面的就读者自己去看一下啦 根据上面的一样逻辑思路很容易就看懂的~
其实这篇文章就是看源码写的文章,看源码主要就是抓住重点,确定自己的目标要看懂什么找什么。只要确定这一点然后一边画代码的流水线图,很容易就找到代码的流向。然后根据看懂了之后再总结一下这些类的作用,这样写有什么好处。
最后附上一副自己在看源码的时候画的图~