Android开发

回顾一下Fragment的生命周期源码

本文主要是介绍回顾一下Fragment的生命周期源码,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

本篇文章带读者走一遍源码Fragment的前几个生命周期,看源码其实有画流程图就不会觉得枯燥。但是写文章我个人倒是觉得写这种读源码文章挺枯燥的。。。哈哈哈 (ps:读者您最好就是开一下IDE,看源码跟着这里面的流程走一下,希望对你自己去看源码会有点帮助)

Fragment生命周期

  • 首先先看一下官网的生命周期图。

Activity与Fragment生命周期对照图
从上面的图可以明显看出来Activity的生命周期与Fragment是相挂钩的。 Activity的生命周期是AMS管理,Fragment的生命周期是被所属Activity管理。

Fragment相关类

我们既然要看Fragment的生命周期,而生命周期是交给Activity管理,且跟Activity的生命周期是相关的,那我们的切入点就可以从Activity的生命中周期着手。且本片文章所看的源码是androidx下的FragmentActivity

Activity与Fragment联动.png

  • FragmentActivity拥有成员对象FragmentController mFragments
  • FragmentController拥有成员对象FragmentHostCallback mHost
  • FragmentHostCallback 拥有成员对象 FragmentManagerImpl mFragmentManager

每个类对应的责任:

  • FragmentController是控制类,对外提供控制Fragment的生命周期等方法,内部实现交由FragmentHostCallback中的FragmentManagerImpl去最终实现。
  • FragmentManagerImpl 是最终处理Fragment所有逻辑的实现类。
  • FragmentHostCallback这个类中拥有了ActivityContext,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: 调用FragmentonCreate方法

 void performCreate(Bundle savedInstanceState) {
       ...省略
        mState = CREATED;
        mCalled = false;
        onCreate(savedInstanceState);//调用Fragment的onCreate方法
        mIsCreated = true;//上个代码块的条件值 mIsCreated的赋值在这里
        ...省略
    }
复制代码

关键点3: 调用FragmentonViewCreated方法

 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() 后面的就读者自己去看一下啦 根据上面的一样逻辑思路很容易就看懂的~

总结

其实这篇文章就是看源码写的文章,看源码主要就是抓住重点,确定自己的目标要看懂什么找什么。只要确定这一点然后一边画代码的流水线图,很容易就找到代码的流向。然后根据看懂了之后再总结一下这些类的作用,这样写有什么好处。

最后附上一副自己在看源码的时候画的图~

Fragment生命周期逻辑图片.jpg

这篇关于回顾一下Fragment的生命周期源码的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!