Fragment源码解析

Posted 流云易采

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Fragment源码解析相关的知识,希望对你有一定的参考价值。

一、Fragment的简单使用:

FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.radio1, tabFourFragment, tabFourFragment.getTag());
transaction.remove(tabFourFragment);
transaction.replace(R.id.radio1, tabFourFragment);
transaction.addToBackStack(tabFourFragment.getTag());
transaction.commit();

主要涉及到的类如下图所示:

通过FragmentActivity来获取FragmentManager,FragmentActivity内部有一个FragmentController对象mFragments,它看起来像是其内部类HostCallBack(继承自FragmentHostCallback)的代理类,代理HostCallback处理众多回调事件;
HostCallBack持有FragmentManager(实际类型为FragmentManagerImpl)对象,用户通过getFragmentManager获取到的即为该对象;
调用FragmentManagerImpl的beginTransaction返回的是一个FragmentTransaction(实际类型为BackStackRecord,它是一个Runnbale),后面的一切add,replace等事务处理操作,都是BackStackRecord创建一个特定类型的Op(Op是一个记录操作事务事件类型的双向链表),然后添加到事件队列中,每一个add等事件对应一个Op;然后在commit时统一通过FragmentManager进行处理,处理的关键函数为moveToState。

二、来看FragmentTransaction的实际类型:

* FragmentActivity#getSupportFragmentManager: *

final FragmentController mFragments = FragmentController.createController(new HostCallbacks());

public FragmentManager getSupportFragmentManager() 
    return mFragments.getSupportFragmentManager();

HostCallbacks主要实现了像onAttachFragment、onStartActivityFromFragment、onFindViewById等回调方法,并且持有FragmentActivity的Activity、Context、Handler等引用,并且为它所持有的FragmentManager提供资源。
FragmentController负责将生命周期分发给它持有的FragmentHostCallback中的FragmentManager。

1、HostCallbacks:

class HostCallbacks extends FragmentHostCallback<FragmentActivity> 
    public HostCallbacks() 
        super(FragmentActivity.this /*fragmentActivity*/);
    

    @Override
    public void onDump(String prefix, FileDescriptor fd, PrintWriter writer, String[] args) 
        FragmentActivity.this.dump(prefix, fd, writer, args);
    

    .......

    @Override
    public boolean onHasWindowAnimations() 
        return getWindow() != null;
    

    @Override
    public int onGetWindowAnimations() 
        final Window w = getWindow();
        return (w == null) ? 0 : w.getAttributes().windowAnimations;
    

    @Override
    public void onAttachFragment(Fragment fragment) 
        FragmentActivity.this.onAttachFragment(fragment);
    

    @Nullable
    @Override
    public View onFindViewById(int id) 
        return FragmentActivity.this.findViewById(id);
    

    @Override
    public boolean onHasView() 
        final Window w = getWindow();
        return (w != null && w.peekDecorView() != null);
    

继续来看FragmentHostCallback:

public abstract class FragmentHostCallback<E> extends FragmentContainer 
    private final Activity mActivity;
    final Context mContext;
    private final Handler mHandler;
    final int mWindowAnimations;
    final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
    private SimpleArrayMap<String, LoaderManager> mAllLoaderManagers;
    private LoaderManagerImpl mLoaderManager;
    private boolean mCheckedForLoaderManager;
    private boolean mLoadersStarted;

    public FragmentHostCallback(Context context, Handler handler, int windowAnimations) 
        this(null, context, handler, windowAnimations);
    

    // 传入进来的构造函数
    FragmentHostCallback(FragmentActivity activity) 
        this(activity, activity , activity.mHandler, 0);
    

    FragmentHostCallback(Activity activity, Context context, Handler handler,
                         int windowAnimations) 
        mActivity = activity;
        mContext = context;
        mHandler = handler;
        mWindowAnimations = windowAnimations;
    

    FragmentManagerImpl getFragmentManagerImpl() 
        return mFragmentManager;
    

可以看到 FragmentHostCallback持有FragmentActivity的activity,Handler,Context的引用,并且创建一个FragmentManagerImpl,它是FragmentManager的具体实现类,这是android常见的用法。

2、FragmentController#createController:

public class FragmentController 
    private final FragmentHostCallback<?> mHost;

    /**
     * Returns a @link FragmentController.
     */
    public static final FragmentController createController(FragmentHostCallback<?> callbacks) 
        return new FragmentController(callbacks);
    

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

    /**
     * Returns a @link FragmentManager for this controller.
     */
    public FragmentManager getSupportFragmentManager() 
        return mHost.getFragmentManagerImpl();
    
    .......

可以看到FragmentController提供的很多方法都是通过FragmentHostCallback来实现的,而之前调用getSupportFragmentManager获取到的也就是在HostCallback中创建的FragmentManagerImpl对象;
下面调用

3、FragmentManagerImpl#beginTransaction:

@Override
public FragmentTransaction beginTransaction() 
    return new BackStackRecord(this);

4、BackStackRecord:

final class BackStackRecord extends FragmentTransaction implements
        FragmentManager.BackStackEntry, Runnable 

    final FragmentManagerImpl mManager;

    public BackStackRecord(FragmentManagerImpl manager) 
        mManager = manager;
    

BackStackRecord是FragmentTransaction的具体实现类,从名称可以看出,它是用来记录BackStack的;而且它集成了Runnable,是一个线程;后面的一系列操作也是基于该类来实现的;
故综上所述:FragmentTransaction的实际类型为BackStackRecord;

三、接下来看FragmentTransaction的操作:

1、BackStackRecord#add:

public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) 
    // 注意传入的动作类型对应为OP_ADD
    doAddOp(containerViewId, fragment, tag, OP_ADD);
    return this;


private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) 
    fragment.mFragmentManager = mManager;

    // 设置fragment的tag
    if (tag != null) 
        // 如果fragment的mTag已经设置
        if (fragment.mTag != null && !tag.equals(fragment.mTag)) 
            throw new IllegalStateException("Can't change tag of fragment "
                    + fragment + ": was " + fragment.mTag
                    + " now " + tag);
        
        fragment.mTag = tag;
    

    // 设置fragment的ContainerId 
    if (containerViewId != 0) 
        if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) 
            throw new IllegalStateException("Can't change container ID of fragment "
                    + fragment + ": was " + fragment.mFragmentId
                    + " now " + containerViewId);
        
        fragment.mContainerId = fragment.mFragmentId = containerViewId;
    

    // 重要类Op,主要的操作都是基于此的
    Op op = new Op();
    op.cmd = opcmd;
    op.fragment = fragment;
    addOp(op);

上面涉及到简单的fragment赋值操作,最重要的引出了一个Op类,FragmentTransaction的所有操作都是基于此来实现的。

2、Op:

final class BackStackRecord extends FragmentTransaction implements
        FragmentManager.BackStackEntry, Runnable 
    // 对应Transaction的各种操作
    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;

    // BackStackRecord的静态内部类
    static final class Op 
        // 明显的双向链表结构
        Op next;
        Op prev;
        // 执行操作类型
        int cmd;
        // 执行的fragment
        Fragment fragment;
        int enterAnim;
        int exitAnim;
        int popEnterAnim;
        int popExitAnim;
        ArrayList<Fragment> removed;
    

    // Op链表的头节点和尾节点
    Op mHead;
    Op mTail;

Op是 BackStackRecord 的静态内部类,是个明显的双向链表结构,其中保存了操作的Fragment引用及操作类型;一个add事件,会创建一个Op对象与之对应,并且调用addOp操作。

3、BackStackRecord#addOp:

// 记录op的总数目
int mNumOp;

// 双向链表的插入操作
void addOp(Op op) 
    if (mHead == null) 
        mHead = mTail = op;
     else 
        op.prev = mTail;
        mTail.next = op;
        mTail = op;
    
    op.enterAnim = mEnterAnim;
    op.exitAnim = mExitAnim;
    op.popEnterAnim = mPopEnterAnim;
    op.popExitAnim = mPopExitAnim;
    mNumOp++;

可以看到FragmentTransaction执行add操作,就是创建一个Op对象,该Op对象记录了要操作的fragmen及操作类型,然后插入到 BackStackRecord中维护的链表中;
那么类似的来看remove等操作:

4、remove,replace等操作:

public FragmentTransaction replace(int containerViewId, Fragment fragment, String tag) 
    if (containerViewId == 0) 
        throw new IllegalArgumentException("Must use non-zero containerViewId");
    

    doAddOp(containerViewId, fragment, tag, OP_REPLACE);
    return this;


public FragmentTransaction remove(Fragment fragment) 
    Op op = new Op();
    op.cmd = OP_REMOVE;
    op.fragment = fragment;
    addOp(op);

    return this;


public FragmentTransaction hide(Fragment fragment) 
    Op op = new Op();
    op.cmd = OP_HIDE;
    op.fragment = fragment;
    addOp(op);

    return this;

逻辑基本一致,只不过修改了Op的cmd变量,即操作类型不同而已;可想而知,最后是通过commit来统一进行处理,这样也维护了事件的原子性。

四、FragmentTransaction的commit操作:

1、先来看addToBackStack:

public FragmentTransaction addToBackStack(String name) 
    if (!mAllowAddToBackStack) 
        throw new IllegalStateException(
                "This FragmentTransaction is not allowed to be added to the back stack.");
    
    mAddToBackStack = true;
    mName = name;
    return this;

这里只是将mAddToBackStack赋值为true,也并未进行实际的处理;来看commit.

2、commit:

public int commit() 
    return commitInternal(false);


public int commitAllowingStateLoss() 
    return commitInternal(true);


int commitInternal(boolean allowStateLoss) 
    // 一次transaction只能commit一次
    if (mCommitted) throw new IllegalStateException("commit already called");
    // 记录该transaction的提交状态
    mCommitted = true;
    // mAddToBackStack就是addToBackStack所设置的
    if (mAddToBackStack) 
        // 这里是添加到BackStack的处理逻辑
        mIndex = mManager.allocBackStackIndex(this);
     else 
        mIndex = -1;
    
    // 具体的处理逻辑
    mManager.enqueueAction(this, allowStateLoss);
    return mIndex;

一个transaction 显然只能commit一次,重复提交就会抛出异常;
allocBackStackIndex是用来处理addToBackStack事件的;
enqueueAction用来处理前面的执行逻辑;
这里先来看enqueueAction,这里的mManager是传递进来的FragmentManagerImpl对象。

3、FragmentManagerImpl#enqueueAction:

FragmentHostCallback mHost; // 前面创建的FragmentHostCallback
boolean mDestroyed;
ArrayList<Runnable> mPendingActions;

Runnable mExecCommit = new Runnable() 
    @Override
    public void run() 
        execPendingActions();
    
;

public void enqueueAction(Runnable action, boolean allowStateLoss) 
    // 这个是和onSavedInstanceState异常恢复相关的
    if (!allowStateLoss) 
        checkStateLoss();
    
    synchronized (this) 
        if (mDestroyed || mHost == null) 
            throw new IllegalStateException("Activity has been destroyed");
        
        if (mPendingActions == null) 
            mPendingActions = new ArrayList<Runnable>();
        

        // 前面提到BackStackRecord是个Runnbale,这里将其添加到一个等待链表中mPendingActions
        mPendingActions.add(action);
        if (mPendingActions.size() == 1) 
            // mHost.getHandler()前面已经提到这里对应Fragment中的Handler
            mHost.getHandler().removeCallbacks(mExecCommit);
            mHost.getHandler().post(mExecCommit);
        
    

前面提到BackStackRecord是个Runnbale,这里将其添加到一个等待链表中mPendingActions中;然后使用FragmentActivity中Handler将mExecCommit这个Runnable Post出去;其主要执行逻辑为execPendingActions方法;继续来看:

3、execPendingActions:

FragmentHostCallback mHost; // 前面创建的FragmentHostCallback
ArrayList<Runnable> mPendingActions;
Runnable[] mTmpActions;
boolean mExecutingActions;

public boolean execPendingActions() 
    if (mExecutingActions) 
        throw new IllegalStateException("Recursive entry to executePendingTransactions");
    

    if (Looper.myLooper() != mHost.getHandler().getLooper()) 
        throw new IllegalStateException("Must be called from main thread of process");
    

    boolean didSomething = false;

    while (true) 
        int numActions;

        synchronized (this) 
            if (mPendingActions == null || mPendingActions.size() == 0) 
                break;
            

            numActions = mPendingActions.size();
            if (mTmpActions == null || mTmpActions.length < numActions) 
                mTmpActions = new Runnable[numActions];
            
            // 将mPendingActions中保存的Action一次性转移到mTmpActions中,然后清空
            mPendingActions.toArray(mTmpActions);
            mPendingActions.clear();
            mHost.getHandler().removeCallbacks(mExecCommit);
        

        mExecutingActions = true;
        // 执行操作
        for (int i=0; i<numActions; i++) 
            mTmpActions[i].run();
            mTmpActions[i] = null;
        
        mExecutingActions = false;
        didSomething = true;
    

    if (mHavePendingDeferredStart) 
        boolean loadersRunning = false;
        for (int i=0; i<mActive.size(); i++) 
            Fragment f = mActive.get(i);
            if (f != null && f.mLoaderManager != null) 
                loadersRunning |= f.mLoaderManager.hasRunningLoaders();
            
        
        if (!loadersRunning) 
            mHavePendingDeferredStart = false;
            startPendingDeferredFragments();
        
    
    return didSomething;

这段逻辑必须在主线程中运行;而且最后调用BackStackRecord的run方法,这里才是真正的逻辑处理的地方。

4、BackStackRecord#run:

public void run() 
    if (mAddToBackStack) 
        if (mIndex < 0) 
            throw new IllegalStateException("addToBackStack() called after commit()");
        
    

    bumpBackStackNesting(1);

    TransitionState state = null;
    SparseArray<Fragment> firstOutFragments = null;
    SparseArray<Fragment> lastInFragments = null;
    if (SUPPORTS_TRANSITIONS) 
        firstOutFragments = new SparseArray<Fragment>();
        lastInFragments = new SparseArray<Fragment>();

        calculateFragments(firstOutFragments, lastInFragments);

        state = beginTransition(firstOutFragments, lastInFragments, false);
    

    int transitionStyle = state != null ? 0 : mTransitionStyle;
    int transition = state != null ? 0 : mTransition;

    // 循环处理这个BackStackRecord中的Op链表中的所有Op
    Op op = mHead;
    while (op != null) 
        int enterAnim = state != null ? 0 : op.enterAnim;
        int exitAnim = state != null ? 0 : op.exitAnim;
        switch (op.cmd) 
            // 对于OP_ADD操作,执行addFragment
            case OP_ADD: 
                Fragment f = op.fragment;
                f.mNextAnim = enterAnim;
                mManager.addFragment(f, false);
             break;
            case OP_REPLACE: 
                Fragment f = op.fragment;
                int containerId = f.mContainerId;
                if (mManager.mAdded != null) 
                    for (int i=0; i<mManager.mAdded.size(); i++) 
                        Fragment old = mManager.mAdded.get(i);
                        if (old.mContainerId == containerId) 
                            if (old == f) 
                                op.fragment = f = null;
                             else 
                                if (op.removed == null) 
                                    op.removed = new ArrayList<Fragment>();
                                
                                op.removed.add(old);
                                old.mNextAnim = exitAnim;
                                if (mAddToBackStack) 
                                    old.mBackStackNesting += 1;
                                
                                mManager.removeFragment(old, transition, transitionStyle);
                            
                        
                    
                
                if (f != null) 
                    f.mNextAnim = enterAnim;
                    mManager.addFragment(f, false);
                
             break;
            case OP_REMOVE: 
                Fragment f = op.fragment;
                f.mNextAnim = exitAnim;
                mManager.removeFragment(f, transition, transitionStyle);
             break;
            case OP_HIDE: 
                Fragment f = op.fragment;
                f.mNextAnim = exitAnim;
                mManager.hideFragment(f, transition, transitionStyle);
             break;
            case OP_SHOW: 
                Fragment f = op.fragment;
                f.mNextAnim = enterAnim;
                mManager.showFragment(f, transition, transitionStyle);
             break;
            case OP_DETACH: 
                Fragment f = op.fragment;
                f.mNextAnim = exitAnim;
                mManager.detachFragment(f, transition, transitionStyle);
             break;
            case OP_ATTACH: 
                Fragment f = op.fragment;
                f.mNextAnim = enterAnim;
                mManager.attachFragment(f, transition, transitionStyle);
             break;
            default: 
                throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
            
        

        op = op.next;
    

    mManager.moveToState(mManager.mCurState, transition, transitionStyle, true);

    if (mAddToBackStack) 
        mManager.addBackStackState(this);
    

代码很长,逻辑很简单,遍历BackStackRecord中保存的Op链表,处理每一个Op事件;每一个Op都对应了一个操作类型比如OP_ADD,其相应的处理是回过来通过FragmentManagerImpl的addFragment来实现的。下面继续分析处理的处理的具体细节。

五、继续前面的流程分析:

1、FragmentManagerImpl#addFragment:

ArrayList<Fragment> mAdded;

public void addFragment(Fragment fragment, boolean moveToStateNow) 
    if (mAdded == null) 
        mAdded = new ArrayList<Fragment>();
    
    // 为Fragment设置index,并添加到mActive数组中
    makeActive(fragment);
    if (!fragment.mDetached) 
        // fragment已经存在
        if (mAdded.contains(fragment)) 
            throw new IllegalStateException("Fragment already added: " + fragment);
        
        // 添加到mAdded中
        mAdded.add(fragment);
        fragment.mAdded = true;
        fragment.mRemoving = false;
        if (fragment.mHasMenu && fragment.mMenuVisible) 
            mNeedMenuInvalidate = true;
        
        // 重要的函数,当前传进来的是false.
        if (moveToStateNow) 
            moveToState(fragment);
        
    



ArrayList<Integer> mAvailIndices;
ArrayList<Fragment> mActive;

void makeActive(Fragment f) 
    // 表示已经是Active状态,即已经在active数组中,则不用Active,直接返回
    if (f.mIndex >= 0) 
        return;
    

    // 如果mActive未创建
    if (mAvailIndices == null || mAvailIndices.size() <= 0) 
        if (mActive == null) 
            mActive = new ArrayList<Fragment>();
        
        // 设置Fragment的index及其在系统内部的Internal Name
        f.setIndex(mActive.size(), mParent);
        // 添加到mActive中
        mActive.add(f);

     else 
        // 同样类似的操作
        f.setIndex(mAvailIndices.remove(mAvailIndices.size()-1), mParent);
        mActive.set(f.mIndex, f);
    

addFragment的主要操作时将当前的Fragment添加到mActive数组(当前Active状态的Fragment集合)以及mAdded数组中;然后进行Fragment相关状态的设置;
对应再来看remove:

2、FragmentManagerImpl#removeFragment

public void removeFragment(Fragment fragment, int transition, int transitionStyle) 
    final boolean inactive = !fragment.isInBackStack();
    // 与Add相对应,从Add数组中中删除
    if (!fragment.mDetached || inactive) 
        if (mAdded != null) 
            mAdded.remove(fragment);
        
        if (fragment.mHasMenu && fragment.mMenuVisible) 
            mNeedMenuInvalidate = true;
        
        fragment.mAdded = false;
        fragment.mRemoving = true;
        moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED,
                transition, transitionStyle, false);
    

removeFragment就是将Fragment从mAdd数组中删除;
而hide,show的主要逻辑是设置Fragment的Visibilty,hide设置为GONE,show设置为VISIBLE。
attach,detach也是操作mAdd.

public void attachFragment(Fragment fragment, int transition, int transitionStyle) 
    if (DEBUG) Log.v(TAG, "attach: " + fragment);
    if (fragment.mDetached) 
        fragment.mDetached = false;
        if (!fragment.mAdded) 
            if (mAdded == null) 
                mAdded = new ArrayList<Fragment>();
            
            if (mAdded.contains(fragment)) 
                throw new IllegalStateException("Fragment already added: " + fragment);
            
            if (DEBUG) Log.v(TAG, "add from attach: " + fragment);
            mAdded.add(fragment);
            fragment.mAdded = true;
            if (fragment.mHasMenu && fragment.mMenuVisible) 
                mNeedMenuInvalidate = true;
            
            moveToState(fragment, mCurState, transition, transitionStyle, false);
        
    


public void detachFragment(Fragment fragment, int transition, int transitionStyle) 
    if (DEBUG) Log.v(TAG, "detach: " + fragment);
    if (!fragment.mDetached) 
        fragment.mDetached = true;
        if (fragment.mAdded) 
            // We are not already in back stack, so need to remove the fragment.
            if (mAdded != null) 
                if (DEBUG) Log.v(TAG, "remove from detach: " + fragment);
                mAdded.remove(fragment);
            
            if (fragment.mHasMenu && fragment.mMenuVisible) 
                mNeedMenuInvalidate = true;
            
            fragment.mAdded = false;
            moveToState(fragment, Fragment.CREATED, transition, transitionStyle, false);
        
    

关键的是看重要的函数moveToState,它是对Fragment状态进行管理的重要的函数。

3、FragmentManagerImpl#moveToState:

Fragment的状态总共分为以下六类:

static final int INITIALIZING = 0;     // 还没有创建
static final int CREATED = 1;          // 创建成功Created.
static final int ACTIVITY_CREATED = 2; // 对应Activity完成了create
static final int STOPPED = 3;          // 创建了,但并未开启start
static final int STARTED = 4;          // 创建了,已经开启,而且没有resume
static final int RESUMED = 5;          // 创建了,并且已经resumed

相对应的状态是按照生命周期状态进行递增的,在moveToState中通过curState转换成newState,比如INITIALIZING到STARTED,中间的四种状态仍然都是要经历的。在moveToState的switch-case中,可以看到每一个switch-case中都没有break;所以会顺序向下执行,而且每一个case中都会有判断,所以上面六种状态升序排序,最终一定会执行到想要设置的状态,而且其生命周期中每个状态都会经历。
而且注意,每一个case对应的是当前的curState,而真正执行的代码块对应的状态是Fragment为newState状态时的响应。即最初判断curState为INITIALIZING时,其对应的newState应该已经为CREATED了;
moveToState的代码较长,分来来看:

(1)前期的一些简单判断:

// 真正的实现逻辑
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
                 boolean keepActive) 
    // 如果当前Fragment的状态并不是ADD状态,或者已经detach,
    // 此时设置的newState比如start等会统一修改为CREATE状态,让Fragment仍停留在create状态
    if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) 
        newState = Fragment.CREATED;
    
    // 当一个fragment正在被remove,该fragment应该保持原来的状态
    if (f.mRemoving && newState > f.mState) 
        // While removing a fragment, we can't change it to a higher state.
        newState = f.mState;
    
    // Defer start if requested; don't allow it to move to STARTED or higher
    // if it's not already started.
    if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) 
        newState = Fragment.STOPPED;
    

(2)来到curState

先来看INITIALIZING==>CREATED状态:

先来了解下Fragment的生命周期:

case Fragment.INITIALIZING:
    // 创建状态
    // mSavedFragmentState是个Bundle,用来保存Fragment异常销毁时的各种状态类型
    // 当期不为null时,则根据其记录的信息进行恢复
    if (f.mSavedFragmentState != null) 
        // 设置ClassLoader
        f.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader());
        // Fragment异常关闭时保存的状态信息
        f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
                FragmentManagerImpl.VIEW_STATE_TAG);
        // 从mActive数组中尝试获取Fragment
        f.mTarget = getFragment(f.mSavedFragmentState,
                FragmentManagerImpl.TARGET_STATE_TAG);
        if (f.mTarget != null) 
            f.mTargetRequestCode = f.mSavedFragmentState.getInt(
                    FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
        
        // 设置UserVisibleHint
        f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
                FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
        // 如果当前不可见,则设置Fragment状态最多为STOPPED,即创建而不启动
        if (!f.mUserVisibleHint) 
            f.mDeferStart = true;
            if (newState > Fragment.STOPPED) 
                newState = Fragment.STOPPED;
            
        
    
    // 设置Fragment的相关参数
    f.mHost = mHost;
    f.mParentFragment = mParent;
    f.mFragmentManager = mParent != null
            ? mParent.mChildFragmentManager : mHost.getFragmentManagerImpl();
    f.mCalled = false;
    // 调用attcah,开启Fragment的相关的生命周期
    // 因为mHost中保存了Fragment的宿主Activity的引用,所以可以直接进行设置,设置mCalled为true,即attach成功
    f.onAttach(mHost.getContext());
    if (!f.mCalled) 
        throw new SuperNotCalledException("Fragment " + f
                + " did not call through to super.onAttach()");
    
    // 如果父Fragment不为空,调用attachFragment
    if (f.mParentFragment == null) 
        mHost.onAttachFragment(f);
    

    // 调用onCreate
    if (!f.mRetaining) 
        f.performCreate(f.mSavedFragmentState);
    
    f.mRetaining = false;
    if (f.mFromLayout) 
        // For fragments that are part of the content view
        // layout, we need to instantiate the view immediately
        // and the inflater will take care of adding it.
        // 调用onCreateView
        f.mView = f.performCreateView(f.getLayoutInflater(
                f.mSavedFragmentState), null, f.mSavedFragmentState);
        if (f.mView != null) 
            f.mInnerView = f.mView;
            if (Build.VERSION.SDK_INT >= 11) 
                ViewCompat.setSaveFromParentEnabled(f.mView, false);
             else 
                f.mView = NoSaveStateFrameLayout.wrap(f.mView);
            
            if (f.mHidden) f.mView.setVisibility(View.GONE);
            // 调用onViewCreated
            f.onViewCreated(f.mView, f.mSavedFragmentState);
         else 
            f.mInnerView = null;
        
    

这里会首先判断是否要对之前销毁的Fragment进行重启,Fragment销毁时保存的状态都保存在 Fragment的mSavedFragmentState中,它是一个Bundle;这里首先对保存了state的Fragment进行恢复;
然后是按照上面的表开始Fragment的生命周期。一个一个来看

1>onAttach
// 因为mHost中保存了Fragment的宿主Activity的引用,所以可以直接进行设置,设置mCalled为true,即attach成功
/**
 * Called when a fragment is first attached to its context.
 * @link #onCreate(Bundle) will be called after this.
 */
public void onAttach(Context context) 
    mCalled = true;
    final Activity hostActivity = mHost == null ? null : mHost.getActivity();
    if (hostActivity != null) 
        mCalled = false;
        onAttach(hostActivity);
    


/**
 * Called when a fragment is first attached to its activity.
 * @link #onCreate(Bundle) will be called after this.
 * <p>Deprecated. See @link #onAttach(Context).
 */
@Deprecated
public void onAttach(Activity activity) 
    mCalled = true;
2>onAttachFragment(如果父Fragment不为空的话)
// HostCallBack
@Override
public void onAttachFragment(Fragment fragment) 
    FragmentActivity.this.onAttachFragment(fragment);


/**
 * Called when a fragment is attached to the activity.
 */
@SuppressWarnings("unused")
public void onAttachFragment(Fragment fragment) 
3>onCreate:
// Fragment.java
void performCreate(Bundle savedInstanceState) 
    if (mChildFragmentManager != null) 
        mChildFragmentManager.noteStateNotSaved();
    
    mCalled = false;
    // 调用onCreate
    onCreate(savedInstanceState);
    if (!mCalled) 
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onCreate()");
    
    // 如果进行恢复的话,注意恢复子Fragment的状态
    if (savedInstanceState != null) 
        Parcelable p = savedInstanceState.getParcelable(
                FragmentActivity.FRAGMENTS_TAG);
        if (p != null) 
            if (mChildFragmentManager == null) 
                instantiateChildFragmentManager();
            
            mChildFragmentManager.restoreAllState(p, null);
            mChildFragmentManager.dispatchCreate();
        
    
4>onCreateView:创建View
View performCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) 
    if (mChildFragmentManager != null) 
        mChildFragmentManager.noteStateNotSaved();
    
    return onCreateView(inflater, container, savedInstanceState);
5>onViewCreated:View创建之后的回调函数,默认为空实现
/**
 * Called immediately after @link #onCreateView(LayoutInflater, ViewGroup, Bundle)
 * has returned, but before any saved state has been restored in to the view.
 * This gives subclasses a chance to initialize themselves once
 * they know their view hierarchy has been completely created.  The fragment's
 * view hierarchy is not however attached to its parent at this point.
 * @param view The View returned by @link #onCreateView(LayoutInflater, ViewGroup, Bundle).
 * @param savedInstanceState If non-null, this fragment is being re-constructed
 * from a previous saved state as given here.
 */
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) 

3)接下来来到CREATE==>ACTIVITY_CREATED状态:

case Fragment.CREATED:
    // Set to true if this fragment was instantiated from a layout file.
    // 表示Fragment是否是通过layout file来初始化的
    // 即在layout中使用fragment创建的静态形式的Fragment在INITIALIZING中创建View
    // 而动态添加的则在CREATE中创建
    boolean mFromLayout;
    if (newState > Fragment.CREATED) 
        // 这里对应于INITIALIZING中的通过layout创建过程
        if (!f.mFromLayout) 
            ViewGroup container = null;
            if (f.mContainerId != 0) 
                container = (ViewGroup)mContainer.onFindViewById(f.mContainerId);
                if (container == null && !f.mRestored) 
                    throwException(new IllegalArgumentException(
                            "No view found for id 0x"
                                    + Integer.toHexString(f.mContainerId) + " ("
                                    + f.getResources().getResourceName(f.mContainerId)
                                    + ") for fragment " + f));
                
            
            f.mContainer = container;
            f.mView = f.performCreateView(f.getLayoutInflater(
                    f.mSavedFragmentState), container, f.mSavedFragmentState);
            if (f.mView != null) 
                f.mInnerView = f.mView;
                if (Build.VERSION.SDK_INT >= 11) 
                    ViewCompat.setSaveFromParentEnabled(f.mView, false);
                 else 
                    f.mView = NoSaveStateFrameLayout.wrap(f.mView);
                
                if (container != null) 
                    Animation anim = loadAnimation(f, transit, true,
                            transitionStyle);
                    if (anim != null) 
                        setHWLayerAnimListenerIfAlpha(f.mView, anim);
                        f.mView.startAnimation(anim);
                    
                    container.addView(f.mView);
                
                if (f.mHidden) f.mView.setVisibility(View.GONE);
                f.onViewCreated(f.mView, f.mSavedFragmentState);
             else 
                f.mInnerView = null;
            
        

        // 调用onActivityCreated
        f.performActivityCreated(f.mSavedFragmentState);
        if (f.mView != null) 
            // 调用onViewStateRestored
            f.restoreViewState(f.mSavedFragmentState);
        
        f.mSavedFragmentState = null;
    

这里除了继续调用生命周期函数外,可以看到Fragment的静态添加和动态添加的两个不同;在layout中使用fragment添加Fragment,其View的创建是在INITIALIZING中;而动态添加的初始化则是在CREATE状态中;

6>performActivityCreated
void performActivityCreated(Bundle savedInstanceState) 
    if (mChildFragmentManager != null) 
        mChildFragmentManager.noteStateNotSaved();
    
    mCalled = false;
    onActivityCreated(savedInstanceState);
    if (!mCalled) 
        throw new SuperNotCalledException("Fragment " 

以上是关于Fragment源码解析的主要内容,如果未能解决你的问题,请参考以下文章

2. Jetpack源码解析---Navigation为什么切换Fragment会重绘?

2. Jetpack源码解析---Navigation为什么切换Fragment会重绘?

Android Lifecycle源码解析

Jetpack-Lifecycle源码解析

Fragment全解析系列:Fragment之我的解决方案:Fragmentation

Android Fragment生命周期及静态加载