Fragment 生命周期怎么来的?

前言

Fragment对于 Android 开发者来说一点都不陌生,因为几乎任何一款 app 都大量使用 Fragment,所以 Fragment 的生命周期相信对于大家来说应该都非常清楚,但绝大部分人对于其生命周期都停留在表象,知道一个 Fragment 从创建到运行再到销毁所要经过的过程,但却不知道内部如何实现。也许有人会这样说,给你一辆摩托车,你只要会骑就行,不需要拆开来看它内部的组成结构;对于这样的问题,我只想说,编程不仅学开车,还要学会造车,并且通过了解实现原理,可以让我们更加清晰的理解 Fragment的生命周期,往往我们通过理解来掌握的东西,是不易忘记的。

Fragment 生命周期流程图

好了,来看下面流程图来回顾一下 Fragment 的生命周期

分析

要分析 Fragment 的生命周期,离不开这四个类

FragmentActivity.javaFragmentManager.javaFragment.javaBackStackRecord.java

启动 app 首先启动的是FragmentActivity,我们就从它开始看起,在 onCreate()方法中

(Bundle savedInstanceState) {//Fragment管理类绑定 ActivitymFragments.attachActivity(this, mContainer, null);// Old versions of the platform didn’t do this!if (getLayoutInflater().getFactory() == null) {getLayoutInflater().setFactory(this);}super.onCreate(savedInstanceState);NonConfigurationInstances nc = (NonConfigurationInstances)getLastNonConfigurationInstance();if (nc != null) {mAllLoaderManagers = nc.loaders;}if (savedInstanceState != null) {Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);mFragments.restoreAllState(p, nc != null ? nc.fragments : null);}mFragments.dispatchCreate();}

这里的mFragments就是FragmentManager,onCreate 中主要做了两件事,一、把FragmentManager和 Activity绑定,二、 向 Fragment分发 OnCreate 方法mFragments.dispatchCreate();看到这里,不知道大家有没有疑问,这里就会执行 Fragment 的onAttach 和 onCreate 方法吗?答案显然是错误的,因为我们都知道我们在执行 add + commit的时候才会执行,那么这里的 attach 和 onCreate 做了什么事?进去看看

(FragmentActivity activity,FragmentContainer container, Fragment parent) {if (mActivity != null) throw new IllegalStateException(“Already attached”);mActivity = activity;mContainer = container;mParent = parent;}

以上代码,只是对变量的赋值,所以不会触发 Fragment 中的方法。

() {mStateSaved = false;moveToState(Fragment.CREATED, false);}

貌似触发了 Fragment 中的 onCreate方法,继续看看;

void moveToState(int newState, int transit, int transitStyle, boolean always) {//…省略部分代码mCurState = newState;if (mActive != null) {boolean loadersRunning = false;for (int i=0; i<mActive.size(); i++) {Fragment f = mActive.get(i);if (f != null) {moveToState(f, newState, transit, transitStyle, false);if (f.mLoaderManager != null) {loadersRunning |= f.mLoaderManager.hasRunningLoaders();}}}//…省略部分代码}

这里有个一判断if (mActive != null),因为我们目前还没有地方初始化它,所以这里显然不成立,所以 dispatchCreate 方法也没有触发Fragment 中的任何方法,但是这里有一个需要注意

mCurState = newState;

也就是说当前状态变成了 Fragment.CREATED

FragmentActivity 中的其他方法如 onStart、onResume 都跟 onCreate 方法一样,都没有触发 Fragment 中的方法, 但mCurState 确发生了改变,变成了最后一个状态的值—> Fragment.RESUMED;

此时 Activity 已经启动了, FragmentManager中的mCurState也已经是Fragment.RESUMED,我们都知道,当我们通过FragmentManager.beginTransaction().add().commit()这时才是正在启动一个 Fragment,通过跟踪代码,commit最终调用的代码如下

public void run() {//….省略很多代码while (op != null) {switch (op.cmd) {case OP_ADD: {//add 会走这里Fragment f = op.fragment;f.mNextAnim = enterAnim;mManager.addFragment(f, false);} break;case OP_REPLACE: {//…省略} break;case OP_REMOVE: {//…省略} break;case OP_HIDE: {//…省略} break;case OP_SHOW: {//…省略} break;case OP_DETACH: {//…省略} break;case OP_ATTACH: {//…省略} break;default: {//…省略}}op = op.next;}//最后会去改变状态,这里就是整个生命周期执行的关键代码mManager.moveToState(mManager.mCurState, transition, transitionStyle, true);if (mAddToBackStack) {mManager.addBackStackState(this);}}

上面代码很长,省略了部分代码,仅显示关键代码,当我们在 add 和 commit 之后,Fragment 会执行mManager.addFragment(f, false);这个方法

if (mAvailIndices == null || mAvailIndices.size() <= 0) {if (mActive == null) {mActive = new ArrayList<Fragment>();}f.setIndex(mActive.size(), mParent);mActive.add(f);} else {//…省略}做事不怕难,自无难人事。

Fragment 生命周期怎么来的?

相关文章:

你感兴趣的文章:

标签云: