本篇文章带读者走一遍源码
Fragment
的前几个生命周期,看源码其实有画流程图就不会觉得枯燥。但是写文章我个人倒是觉得写这种读源码文章挺枯燥的。。。哈哈哈 (ps:读者您最好就是开一下IDE,看源码跟着这里面的流程走一下,希望对你自己去看源码会有点帮助)
Fragment生命周期
- 首先先看一下官网的生命周期图。
![](https://img.haomeiwen.com/i6459481/5d1910ac29e9c695.png)
从上面的图可以明显看出来
Activity
的生命周期与Fragment
是相挂钩的。Activity
的生命周期是AMS
管理,Fragment
的生命周期是被所属Activity
管理。
Fragment相关类
我们既然要看Fragment
的生命周期,而生命周期是交给Activity
管理,且跟Activity
的生命周期是相关的,那我们的切入点就可以从Activity
的生命中周期着手。且本片文章所看的源码是androidx
下的FragmentActivity
![](https://img.haomeiwen.com/i6459481/966bae8db965409d.png)
-
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()
后面的就读者自己去看一下啦 根据上面的一样逻辑思路很容易就看懂的~
总结
其实这篇文章就是看源码写的文章,看源码主要就是抓住重点,确定自己的目标要看懂什么找什么。只要确定这一点然后一边画代码的流水线图,很容易就找到代码的流向。然后根据看懂了之后再总结一下这些类的作用,这样写有什么好处。
最后附上一副自己在看源码的时候画的图~
![](https://img.haomeiwen.com/i6459481/4ac6af07c4fd45eb.jpg)
网友评论