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();

主要涉及到的类如下图所示:
Fragment源码解析_第1张图片

通过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的生命周期:
Fragment源码解析_第2张图片

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 " + this
                + " did not call through to super.onActivityCreated()");
    }
    if (mChildFragmentManager != null) {
        mChildFragmentManager.dispatchActivityCreated();
    }
}
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    mCalled = true;
}
7>restoreViewState
final void restoreViewState(Bundle savedInstanceState) {
    if (mSavedViewState != null) {
        mInnerView.restoreHierarchyState(mSavedViewState);
        mSavedViewState = null;
    }
    mCalled = false;
    onViewStateRestored(savedInstanceState);
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onViewStateRestored()");
    }
}
public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
    mCalled = true;
}

4)继续往下来到ACTIVITY_CREATED==>STOP==>STARTED状态:

case Fragment.ACTIVITY_CREATED:
case Fragment.STOPPED:
    if (newState > Fragment.STOPPED) {
        if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
        f.performStart();
    }
8> performStart:
void performStart() {
    if (mChildFragmentManager != null) {
        mChildFragmentManager.noteStateNotSaved();
        mChildFragmentManager.execPendingActions();
    }
    mCalled = false;
    onStart();
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onStart()");
    }
    if (mChildFragmentManager != null) {
        mChildFragmentManager.dispatchStart();
    }
    if (mLoaderManager != null) {
        mLoaderManager.doReportStart();
    }
}

public void onStart() {
    mCalled = true;

    if (!mLoadersStarted) {
        mLoadersStarted = true;
        if (!mCheckedForLoaderManager) {
            mCheckedForLoaderManager = true;
            mLoaderManager = mHost.getLoaderManager(mWho, mLoadersStarted, false);
        }
        if (mLoaderManager != null) {
            mLoaderManager.doStart();
        }
    }
}

5)STRAT==>RESUME对应onResume:

case Fragment.STARTED:
    if (newState > Fragment.STARTED) {
        if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
        f.mResumed = true;
        f.performResume();
        f.mSavedFragmentState = null;
        f.mSavedViewState = null;
    }
9>performResume:
void performResume() {
    if (mChildFragmentManager != null) {
        mChildFragmentManager.noteStateNotSaved();
        mChildFragmentManager.execPendingActions();
    }
    mCalled = false;
    onResume();
    if (!mCalled) {
        throw new SuperNotCalledException("Fragment " + this
                + " did not call through to super.onResume()");
    }
    if (mChildFragmentManager != null) {
        mChildFragmentManager.dispatchResume();
        mChildFragmentManager.execPendingActions();
    }
}

public void onResume() {
    mCalled = true;
}

(3)再来到f.mState > newState:

再来看逆向销毁的过程,基本上生命周期流程图中的相匹配;

else if (f.mState > newState) {
    switch (f.mState) {
        case Fragment.RESUMED:
            if (newState < Fragment.RESUMED) {
                if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
                // 执行onPause
                f.performPause();
                f.mResumed = false;
            }
        case Fragment.STARTED:
            if (newState < Fragment.STARTED) {
                if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
                // 执行onStop
                f.performStop();
            }
        case Fragment.STOPPED:
            // 执行onReallyStop
            if (newState < Fragment.STOPPED) {
                if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
                f.performReallyStop();
            }
        case Fragment.ACTIVITY_CREATED:
            if (newState < Fragment.ACTIVITY_CREATED) {
                if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
                if (f.mView != null) {
                    // Need to save the current view state if not
                    // done already.
                    if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
                        // 保存View的状态
                        saveFragmentViewState(f);
                    }
                }
                // onDestroyView
                f.performDestroyView();
                if (f.mView != null && f.mContainer != null) {
                    Animation anim = null;
                    if (mCurState > Fragment.INITIALIZING && !mDestroyed) {
                        anim = loadAnimation(f, transit, false,
                                transitionStyle);
                    }
                    if (anim != null) {
                        final Fragment fragment = f;
                        f.mAnimatingAway = f.mView;
                        f.mStateAfterAnimating = newState;
                        final View viewToAnimate = f.mView;
                        anim.setAnimationListener(new AnimateOnHWLayerIfNeededListener(
                                viewToAnimate, anim) {
                            @Override
                            public void onAnimationEnd(Animation animation) {
                                super.onAnimationEnd(animation);
                                if (fragment.mAnimatingAway != null) {
                                    fragment.mAnimatingAway = null;
                                    moveToState(fragment, fragment.mStateAfterAnimating,
                                            0, 0, false);
                                }
                            }
                        });
                        f.mView.startAnimation(anim);
                    }
                    f.mContainer.removeView(f.mView);
                }
                f.mContainer = null;
                f.mView = null;
                f.mInnerView = null;
            }
        case Fragment.CREATED:
            if (newState < Fragment.CREATED) {
                if (mDestroyed) {
                    if (f.mAnimatingAway != null) {
                        // The fragment's containing activity is
                        // being destroyed, but this fragment is
                        // currently animating away. Stop the
                        // animation right now -- it is not needed,
                        // and we can't wait any more on destroying
                        // the fragment.
                        View v = f.mAnimatingAway;
                        f.mAnimatingAway = null;
                        v.clearAnimation();
                    }
                }
                if (f.mAnimatingAway != null) {
                    // We are waiting for the fragment's view to finish
                    // animating away. Just make a note of the state
                    // the fragment now should move to once the animation
                    // is done.
                    f.mStateAfterAnimating = newState;
                    newState = Fragment.CREATED;
                } else {
                    if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
                    if (!f.mRetaining) {
                        // 调用onDestroy
                        f.performDestroy();
                    }

                    f.mCalled = false;
                    // onDetach
                    f.onDetach();
                    if (!f.mCalled) {
                        throw new SuperNotCalledException("Fragment " + f
                                + " did not call through to super.onDetach()");
                    }
                    if (!keepActive) {
                        if (!f.mRetaining) {

                            makeInactive(f);
                        } else {
                            f.mHost = null;
                            f.mParentFragment = null;
                            f.mFragmentManager = null;
                            f.mChildFragmentManager = null;
                        }
                    }
                }
            }
    }
}

f.mState = newState;

生命周期函数不再详述,来重点看下onDetach回到INITIALIZING状态后的makeInactive函数:

void makeInactive(Fragment f) {
    if (f.mIndex < 0) {
        return;
    }

    // 这里将该Fragment对应的位置的引用设为null,并未清除
    mActive.set(f.mIndex, null);
    if (mAvailIndices == null) {
        mAvailIndices = new ArrayList<Integer>();
    }
    // 而创建了一个mAvailIndices来保存销毁的f.mIndex
    mAvailIndices.add(f.mIndex);
    // 根据f的mWho tag设置为inActive状态
    mHost.inactivateFragment(f.mWho);
    // 初始化该Fragment中的所有状态
    f.initState();
}

void inactivateFragment(String who) {
    //Log.v(TAG, "invalidateSupportFragment: who=" + who);
    if (mAllLoaderManagers != null) {
        LoaderManagerImpl lm = (LoaderManagerImpl) mAllLoaderManagers.get(who);
        if (lm != null && !lm.mRetaining) {
            lm.doDestroy();
            mAllLoaderManagers.remove(who);
        }
    }
}

final SparseArrayCompat<LoaderInfo> mLoaders = new SparseArrayCompat<LoaderInfo>();
void doDestroy() {
    // 
    if (!mRetaining) {
        if (DEBUG) Log.v(TAG, "Destroying Active in " + this);
        for (int i = mLoaders.size()-1; i >= 0; i--) {
            mLoaders.valueAt(i).destroy();
        }
        mLoaders.clear();
    }

    if (DEBUG) Log.v(TAG, "Destroying Inactive in " + this);
    for (int i = mInactiveLoaders.size()-1; i >= 0; i--) {
        mInactiveLoaders.valueAt(i).destroy();
    }
    mInactiveLoaders.clear();
}

总结以上的生命周期:

所以FragmentTransaction中的几种动态操作Fragment的方法,其中的主要区别都是通过设置moveToState中不同的State来实现的。
add:添加Fragment;
remove:删除Fragment,而且会销毁Fragment实例;注意在removeFragment中

moveToState(fragment, inactive ? Fragment.INITIALIZING : Fragment.CREATED,
                transition, transitionStyle, false);

replace:先调用removeFragment,再调用addFragment;
hide:隐藏;设置visibility=gone;
show:显示;通过设置VISIBILITY=VISIBILE来实现。
attach:添加到mAdded数组中,不改变当前状态;

moveToState(fragment, mCurState, transition, transitionStyle, false);

detach:设置Fragment的状态为CREATED,并未调用onDestory和onDetach来销毁Fragment实例,只是destroyView

moveToState(fragment, Fragment.CREATED, transition, transitionStyle, false);

你可能感兴趣的:(Fragment源码解析)