Fragment 生命周期源码分析

dependencies {
    val fragment_version = "1.3.4"

    // Java language implementation
    implementation("androidx.fragment:fragment:$fragment_version")
    // Kotlin
    implementation("androidx.fragment:fragment-ktx:$fragment_version")
    // Testing Fragments in Isolation
    debugImplementation("androidx.fragment:fragment-testing:$fragment_version")
}
  • Fragment 无论是单独使用还是配合Viewpager,对于Android开发来说非常熟悉了,但生命周期,一般就网上看到的一张图,想必大家也经常看到;
    Fragment lifecyclee
  • 那Fragment的生命周期在什么时候调用的,commit之后怎么走到生命周期的每一个方法,需要看源码才知道,本文就此分析。

1.supportFragmentManager

  • 只有使用 FragmentActivity 才有 supportFragmentManager
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.test_activity3_activity)
    if (savedInstanceState == null) {
        supportFragmentManager.beginTransaction()
            .replace(R.id.container, TestActivity3Fragment.newInstance())
            .commitNow()
    }
}

1.1 getSupportFragmentManager

  • FragmentActivity里面的 mFragments 可不是Fragment数组哦,他是 FragmentController ,这个很重要,先记住他。
     /* FragmentActivity类 */
     
     //创建FragmentController 
    final FragmentController mFragments = FragmentController.createController(new HostCallbacks());

    /**
     * Return the FragmentManager for interacting with fragments associated
     * with this activity.
     */
    @NonNull
    public FragmentManager getSupportFragmentManager() {
        return mFragments.getSupportFragmentManager();
    }

1.2 FragmentController类

  • new HostCallbacks() 传进去,再获取 SupportFragmentManager。
public class FragmentController {
    private final FragmentHostCallback<?> mHost;

    /**
     * Returns a {@link FragmentController}.
     */
    @NonNull
    public static FragmentController createController(@NonNull FragmentHostCallback<?> callbacks) {
        return new FragmentController(checkNotNull(callbacks, "callbacks == null"));
    }

    private FragmentController(FragmentHostCallback<?> callbacks) {
        mHost = callbacks;
    }

    /**
     * 通过mHost获取FragmentManager
     * Returns a {@link FragmentManager} for this controller.
     */
    @NonNull
    public FragmentManager getSupportFragmentManager() {
        return mHost.mFragmentManager;
    }
}

1.3 FragmentHostCallback类

  • FragmentHostCallback 里获取 mFragmentManager
  • FragmentManagerImpl 继承FragmentManager,但什么都没做。
public abstract class FragmentHostCallback<E> extends FragmentContainer {
    @Nullable private final Activity mActivity;
    @NonNull private final Context mContext;
    @NonNull private final Handler mHandler;
    private final int mWindowAnimations;
    final FragmentManager mFragmentManager = new FragmentManagerImpl();//继承FragmentManager,但什么都没做
class FragmentManagerImpl extends FragmentManager {
}
  • 到此就获取一个fragmentManager。

2.beginTransaction

  • 每次处理Fragment的事务都是新建一个 BackStackRecord 回退栈 ,只能用一次。
    @NonNull
    public FragmentTransaction beginTransaction() {
        return new BackStackRecord(this);
    }

2.1 FragmentTransaction类

  • BackStackRecord 类是继承 抽象类FragmentTransaction,这里有非常重要的各个OP常量,还有内部类OP。
  • add,hide,remove等操作也是在这个类,他们都会封装进Op,用数组mOps 保存。
public abstract class FragmentTransaction {

    static final int OP_NULL = 0;
    static final int OP_ADD = 1;
    static final int OP_REPLACE = 2;
    static final int OP_REMOVE = 3;
    static final int OP_HIDE = 4;
    static final int OP_SHOW = 5;
    static final int OP_DETACH = 6;
    static final int OP_ATTACH = 7;
    static final int OP_SET_PRIMARY_NAV = 8;
    static final int OP_UNSET_PRIMARY_NAV = 9;
    static final int OP_SET_MAX_LIFECYCLE = 10;
    .
    .
    ArrayList<Op> mOps = new ArrayList<>();
}

2.2 Op类

  • Op这个类对于后面add,hide,remove等操作很重要。
static final class Op {
        int mCmd;
        Fragment mFragment;
        int mEnterAnim;
        int mExitAnim;
        int mPopEnterAnim;
        int mPopExitAnim;
        Lifecycle.State mOldMaxState;
        Lifecycle.State mCurrentMaxState;

        Op() {
        }
        .
        .
}

2.3 BackStackRecord类

  • 这个类就是真正执行提交事务的类,提交事务会把自己一起传给FragmentManager。
  • 还实现了 FragmentManager.OpGenerator 接口。
final class BackStackRecord extends FragmentTransaction implements
        FragmentManager.BackStackEntry, FragmentManager.OpGenerator {
       final FragmentManager mManager;

	@Override
    public int commit() {
        return commitInternal(false);
    }

    @Override
    public int commitAllowingStateLoss() {
        return commitInternal(true);
    }

    @Override
    public void commitNow() {
        disallowAddToBackStack();
        mManager.execSingleAction(this, false);
    }

    @Override
    public void commitNowAllowingStateLoss() {
        disallowAddToBackStack();
        mManager.execSingleAction(this, true);
    }

3.add,hide,replace,remove

3.1 封装,addOp

  • 这里就分析一个replace,其他也是差不多的。
  • 这里做的就是把要替换的控件id,fragment,tag,操作对应的常量封装进Op类里。
/*FragmentTransaction*/

    /**
     * Calls {@link #replace(int, Fragment, String)} with a null tag.
     */
    @NonNull
    public FragmentTransaction replace(@IdRes int containerViewId, @NonNull Fragment fragment) {
        return replace(containerViewId, fragment, null);
    }

    @NonNull
    public FragmentTransaction replace(@IdRes int containerViewId, @NonNull Fragment fragment,
            @Nullable String tag)  {
        //判断数据有效性
        if (containerViewId == 0) {
            throw new IllegalArgumentException("Must use non-zero containerViewId");
        }
        doAddOp(containerViewId, fragment, tag, OP_REPLACE);
        return this;
    }


    void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
       .
       .
		//封装进Op
        addOp(new Op(opcmd, fragment));
    }

    /**
     * mOps 数组保持着这些操作
     * 把fragment进入退出动画一起加上,
     * 可以去setCustomAnimations方法看
     */
    void addOp(Op op) {
        mOps.add(op);
        op.mEnterAnim = mEnterAnim;
        op.mExitAnim = mExitAnim;
        op.mPopEnterAnim = mPopEnterAnim;
        op.mPopExitAnim = mPopExitAnim;
    }

4.commit

4.1 四种提交方式

  • 提交事务有四种,分别是,先不分析四种区别,不是本次重点。
1. commit()
2. commitAllowingStateLoss()
3. commitNow()
4. commitNowAllowingStateLoss()

4.2 提交事务

  • commit 只能操作一次,一次就把add,hide,replace等操作一起提交。
  • 提交事务其实就是把自己一起丢给FragmentManager执行。
    @Override
    public int commit() {
        return commitInternal(false);
    }
    
    int commitInternal(boolean allowStateLoss) {
        //只能commit一次,否则抛异常
        if (mCommitted) throw new IllegalStateException("commit already called");
        if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
            Log.v(TAG, "Commit: " + this);
            LogWriter logw = new LogWriter(TAG);
            PrintWriter pw = new PrintWriter(logw);
            dump("  ", pw);
            pw.close();
        }
        mCommitted = true;
        //是否加入回退栈
        if (mAddToBackStack) {
            // 放入回退栈标记的index
            mIndex = mManager.allocBackStackIndex();
        } else {
            mIndex = -1;
        }
        //操作入队
        mManager.enqueueAction(this, allowStateLoss);
        return mIndex;
    }

4.3 handler 发送

  • commit 是在主线程异步执行,就是通过handler执行。
 /*FragmentManager*/

	//保存操作
    private final ArrayList<OpGenerator> mPendingActions = new ArrayList<>();
 
    void enqueueAction(@NonNull OpGenerator action, boolean allowStateLoss) {
    
        if (!allowStateLoss) {
            if (mHost == null) {
                if (mDestroyed) {
                	//FragmentManager 已经 销毁
                    throw new IllegalStateException("FragmentManager has been destroyed");
                } else {
                	//FragmentManager 还没绑定
                    throw new IllegalStateException("FragmentManager has not been attached to a "
                            + "host.");
                }
            }
            checkStateLoss();
        }
        //加锁
        synchronized (mPendingActions) {
            if (mHost == null) {
           	 	//commitAllowingStateLoss会走这里
                if (allowStateLoss) {
                    // This FragmentManager isn't attached, so drop the entire transaction.
                    return;
                }
                throw new IllegalStateException("Activity has been destroyed");
            }
            //加入到数组
            mPendingActions.add(action);
            //最终来到这里
            scheduleCommit();
        }
    }
  • 到这终于看到handler了,用post(Runnable)发送出去。
    void scheduleCommit() {
        synchronized (mPendingActions) {
            boolean postponeReady =
                    mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
            boolean pendingReady = mPendingActions.size() == 1;
            if (postponeReady || pendingReady) {
            	//handler处理
                mHost.getHandler().removeCallbacks(mExecCommit);
                mHost.getHandler().post(mExecCommit);
                updateOnBackPressedCallbackEnabled();
            }
        }
    }

4.4 执行execPendingActions

    private Runnable mExecCommit = new Runnable() {
        @Override
        public void run() {
            execPendingActions(true);
        }
    };

    /**
     * Only call from main thread!
     */
    boolean execPendingActions(boolean allowStateLoss) {
        ensureExecReady(allowStateLoss);

        boolean didSomething = false;
        //把事务放入临时变量
        while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
            mExecutingActions = true;
            try { 
            	//优化整理事务           
                removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
            } finally {
                cleanupExec();
            }
            didSomething = true;
        }

        ...
        return didSomething;
    }

4.5 整理事务

  • removeRedundantOperationsAndExecute 有一大段注释,注释的意思就是说这方法删除冗余的操作,合并重复的操作,就是优化整理
  • 重点看到 record.expandOps 方法。
  • 拿出 Op 里面记录的操作,对不同操作处理,added增加或者移除,替换就是先移除再添加,具体可以看源码,这里就不贴全部了,有点多。
	/*FragmentManager*/
	
	/**
     * Remove redundant BackStackRecord operations and executes them. This method merges operations
     * of proximate records that allow reordering. See
    ...
     */
    private void removeRedundantOperationsAndExecute(@NonNull ArrayList<BackStackRecord> records,
            @NonNull ArrayList<Boolean> isRecordPop) {
      ...
      
      executeOpsTogether(records, isRecordPop, startIndex, recordNum);
		...


    private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records,
            @NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
       //展开整理
       oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
	...
}
	//展开整理
   Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
        for (int opNum = 0; opNum < mOps.size(); opNum++) {
            final Op op = mOps.get(opNum);
            switch (op.mCmd) {   
            	//添加       
                case OP_ADD:
                case OP_ATTACH:
                    added.add(op.mFragment);
                    break;
                //移除
                case OP_REMOVE:
                case OP_DETACH: {
                    added.remove(op.mFragment);
                    if (op.mFragment == oldPrimaryNav) {
                        mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.mFragment));
                        opNum++;
                        oldPrimaryNav = null;
                    }
                }
                break;
                //替换
                case OP_REPLACE: {
                   ...
                }
                break;
                case OP_SET_PRIMARY_NAV: {
                   ...
                }
                break;
            }
        }
        return oldPrimaryNav;
    }

4.6 执行事务

  • 这里的FragmentManager.executeOps方法,再进入 BackStackRecord.executeOps方法,根据Op信息,处理再回到FragmentManager.moveToState方法。
	/*FragmentManager*/
 	private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records,
            @NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
        
        ...
        executeOps(records, isRecordPop, startIndex, endIndex);
        ...private static void executeOps(@NonNull ArrayList<BackStackRecord> records,
            @NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
       ..
       record.executeOps();

	
	/*BackStackRecord*/
    void executeOps() {
        final int numOps = mOps.size();
        for (int opNum = 0; opNum < numOps; opNum++) {
            final Op op = mOps.get(opNum);
            final Fragment f = op.mFragment;
           ...
            switch (op.mCmd) {
                case OP_ADD:
                    f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
                    mManager.setExitAnimationOrder(f, false);
                    mManager.addFragment(f);
                    break;
              .
              .
              .              
            }           
        }
        if (!mReorderingAllowed && !FragmentManager.USE_STATE_MANAGER) {
            // Added fragments are added at the end to comply with prior behavior.
            mManager.moveToState(mManager.mCurState, true);
        }
    }

4.7 状态改变

  • 首先我们能看到Fragment 的状态常量有哪些,其实有的版本,比如1.2.0只有5个,那这几个怎么够呢,好像生命周期不止这几个啊,就是创建时正着来,销毁时再反着来就行了。
public class Fragment implements ... {

    static final Object USE_DEFAULT_TRANSITION = new Object();

    static final int INITIALIZING = -1;          // Not yet attached.
    static final int ATTACHED = 0;               // Attached to the host.
    static final int CREATED = 1;                // Created.
    static final int VIEW_CREATED = 2;           // View Created.
    static final int AWAITING_EXIT_EFFECTS = 3;  // Downward state, awaiting exit effects
    static final int ACTIVITY_CREATED = 4;       // Fully created, not started.
    static final int STARTED = 5;                // Created and started, not resumed.
    static final int AWAITING_ENTER_EFFECTS = 6; // Upward state, awaiting enter effects
    static final int RESUMED = 7;                // Created started and resumed.

    int mState = INITIALIZING;
}
  • moveToState的代码是本次关键。
  • newState = Math.min(newState, fragmentStateManager.computeExpectedState()),这里跟官方提供的懒加载有关,可以限制fragment执行到哪个阶段,但现在先不管他。
  • if (f.mState <= newState) ,如果true , 可以看到后面的代码是创建流程,比如 Fragment.INITIALIZING ,ATTACHED,CREATED等等,否则就是销毁流程,这里就放一部分代码,可以自己去源码看看所有流程。
    void moveToState(int newState, boolean always) {
       ...
        moveFragmentToExpectedState(f);
       ...   
    }
    
    void moveFragmentToExpectedState(@NonNull Fragment f) {
      	...
        moveToState(f);
		...
    }
    
    void moveToState(@NonNull Fragment f) {
        moveToState(f, mCurState);
    }

   void moveToState(@NonNull Fragment f, int newState) {
   		//获取FragmentStateManager 
        FragmentStateManager fragmentStateManager = mFragmentStore.getFragmentStateManager(f.mWho);
        if (fragmentStateManager == null) {
          
            fragmentStateManager = new FragmentStateManager(mLifecycleCallbacksDispatcher,
                    mFragmentStore, f);
           
            fragmentStateManager.setFragmentManagerState(Fragment.CREATED);
        }
     
        if (f.mFromLayout && f.mInLayout && f.mState == Fragment.VIEW_CREATED) {
            newState = Math.max(newState, Fragment.VIEW_CREATED);
        }
		//这里跟官方提供的懒加载有关,可以限制fragment执行到哪个阶段
        newState = Math.min(newState, fragmentStateManager.computeExpectedState());
        if (f.mState <= newState) {
            // If we are moving to the same state, we do not need to give up on the animation.
            if (f.mState < newState && !mExitAnimationCancellationSignals.isEmpty()) {
                // The fragment is currently being animated...  but!  Now we
                // want to move our state back up.  Give up on waiting for the
                // animation and proceed from where we are.
                cancelExitAnimation(f);
            }
            switch (f.mState) {
                case Fragment.INITIALIZING:
                    if (newState > Fragment.INITIALIZING) {
                        fragmentStateManager.attach();
                    }
                    // fall through
                case Fragment.ATTACHED:
                    if (newState > Fragment.ATTACHED) {
                        fragmentStateManager.create();
                    }
                    // fall through
                case Fragment.CREATED:
                    // We want to unconditionally run this anytime we do a moveToState that
                    // moves the Fragment above INITIALIZING, including cases such as when
                    // we move from CREATED => CREATED as part of the case fall through above.
                    if (newState > Fragment.INITIALIZING) {
                        fragmentStateManager.ensureInflatedView();
                    }

                    if (newState > Fragment.CREATED) {
                        fragmentStateManager.createView();
                    }
                    // fall through
                ...
                
            }
        } else if (f.mState > newState) {
            switch (f.mState) {
                case Fragment.RESUMED:
                    if (newState < Fragment.RESUMED) {
                        fragmentStateManager.pause();
                    }
                    // fall through
                case Fragment.STARTED:
                    if (newState < Fragment.STARTED) {
                        fragmentStateManager.stop();
                    }
                    // fall through
                ...
            }
        }

        if (f.mState != newState) {
            if (isLoggingEnabled(Log.DEBUG)) {
                Log.d(TAG, "moveToState: Fragment state for " + f + " not updated inline; "
                        + "expected state " + newState + " found " + f.mState);
            }
            f.mState = newState;
        }
    }

4.8 终于到fragment的生命周期执行

  • 这里有一个FragmentStateManager,就是他才是真正的调用Fragment 的生命周期方法,我们终于看到熟悉的身影,Fragment 的 onCreateView方法。
  • 这里看onCreateView ,我们最常用的方法,其他也是一样样的,大家也可以尝试自己去分析。
 case Fragment.CREATED:                    
       if (newState > Fragment.CREATED) {
           fragmentStateManager.createView();
       }


	/*FragmentStateManager*/
	 void createView() {
	 	...
        mFragment.performCreateView(layoutInflater, container, mFragment.mSavedFragmentState);
        .../*Fragment*/
	 void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState) {
        mChildFragmentManager.noteStateNotSaved();
        mPerformedCreateView = true;
        mViewLifecycleOwner = new FragmentViewLifecycleOwner(getViewModelStore());
        mView = onCreateView(inflater, container, savedInstanceState);
        if (mView != null) {
            // Initialize the view lifecycle
            mViewLifecycleOwner.initialize();
            // Tell the fragment's new view about it before we tell anyone listening
            // to mViewLifecycleOwnerLiveData and before onViewCreated, so that calls to
            // ViewTree get() methods return something meaningful
            ViewTreeLifecycleOwner.set(mView, mViewLifecycleOwner);
            ViewTreeViewModelStoreOwner.set(mView, mViewLifecycleOwner);
            ViewTreeSavedStateRegistryOwner.set(mView, mViewLifecycleOwner);
            // Then inform any Observers of the new LifecycleOwner
            mViewLifecycleOwnerLiveData.setValue(mViewLifecycleOwner);
        } else {
            if (mViewLifecycleOwner.isInitialized()) {
                throw new IllegalStateException("Called getViewLifecycleOwner() but "
                        + "onCreateView() returned null");
            }
            mViewLifecycleOwner = null;
        }
    }

5.流程图

  • 搭配流程图看可能会好一些。
    流程图
  • 如果有错帮忙指出,谢谢。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android开发中,Fragment是一个可重用的UI部分,它可以独立于Activity存在,并且可以根据需要添加到不同的Activity中。Fragment有自己的生命周期管理,这包括一系列的方法,用于描述Fragment从创建、显示、活跃到销毁的整个过程。 1. **onCreate()**: 当Fragment实例被创建时调用,这是初始化阶段,可以在此设置基本属性和数据。 2. **onCreateView()**: 如果Fragment没有预先创建视图,这个方法会被调用来生成视图。返回null则会使用默认布局。 3. **onStart()**: 当Fragment成为活动焦点或可见时调用,可以在这里开始执行耗时操作。 4. **onResume()**: 当Fragment变为活动的前景或者用户正在交互时,这个方法会被调用,意味着它是完全活跃的。 5. **onPause()**: 当Fragment不再接收用户交互或成为活动焦点时,但依然可见时,这个方法会被调用。 6. **onStop()**: 当Fragment失去焦点并且不处于可见状态时,例如切换到其他Activity,这个方法会被调用。 7. **onDestroyView()**: 当Fragment的视图不再需要时,这个方法会被调用,通常在onPause之后。 8. **onSaveInstanceState()**: 在onPause或onStop之前调用,用于保存Fragment的状态,以便在恢复时使用。 9. **onDestroy()**: 当Fragment被系统卸载,不再需要内存时,这个方法会被调用。 10. **onActivityCreated()**: 当Fragment的视图已经创建完毕,并且所有的依赖项都可用时,这个方法会被调用。 11. **onDestroyView()**: 视图销毁后调用,释放资源。 12. **onDetach()**: 当Fragment从其宿主Activity中分离出来时,这个方法会被调用,通常发生在用户切换回其他Activity时。 理解Fragment生命周期对于管理其行为、数据和资源至关重要。开发者可以根据这些阶段进行必要的资源管理、数据保存和状态更新。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值