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。
* 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。
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常见的用法。
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对象;
下面调用
@Override
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, Runnable {
final FragmentManagerImpl mManager;
public BackStackRecord(FragmentManagerImpl manager) {
mManager = manager;
}
}
BackStackRecord是FragmentTransaction的具体实现类,从名称可以看出,它是用来记录BackStack的;而且它集成了Runnable,是一个线程;后面的一系列操作也是基于该类来实现的;
故综上所述:FragmentTransaction的实际类型为BackStackRecord;
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的所有操作都是基于此来实现的。
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操作。
// 记录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等操作:
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来统一进行处理,这样也维护了事件的原子性。
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.
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对象。
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方法;继续来看:
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方法,这里才是真正的逻辑处理的地方。
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来实现的。下面继续分析处理的处理的具体细节。
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:
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状态进行管理的重要的函数。
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的代码较长,分来来看:
// 真正的实现逻辑
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;
}
}
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的生命周期。一个一个来看
// 因为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;
}
// 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) {
}
// 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();
}
}
}
View performCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if (mChildFragmentManager != null) {
mChildFragmentManager.noteStateNotSaved();
}
return onCreateView(inflater, container, savedInstanceState);
}
/** * 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) {
}
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状态中;
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;
}
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;
}
case Fragment.ACTIVITY_CREATED:
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
f.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();
}
}
}
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;
}
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;
}
再来看逆向销毁的过程,基本上生命周期流程图中的相匹配;
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);