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会重绘?