在上一篇文章中介绍了 Fragment
的状态保存和状态恢复:Androidx Fragment 源码阅读笔记(上)。
本篇文章继续阅读 Fragment
提交事务后,是如何更新我们的 Fragment
状态。
以下先给一个提交事务的 demo:
Kotlin
val tc = this@MyFragmentActivity.supportFragmentManager.beginTransaction()
tc.setMaxLifecycle(myFragments[FragmentType.A]!!, Lifecycle.State.CREATED)
tc.commitNowAllowingStateLoss()
先看看 FragmentTransaction
是如何创建的:
Java
@NonNull
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
@NonNull
public FragmentManager getSupportFragmentManager() {
return mHost.mFragmentManager;
}
@NonNull
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
FragmentTransaction
是一个抽象类,我们使用的实现类是 BackStackRecord
。
我们先来看看 FragmentTransaction#setMaxLifecycle()
的实现:
Java
@NonNull
public FragmentTransaction setMaxLifecycle(@NonNull Fragment fragment,
@NonNull Lifecycle.State state) {
addOp(new Op(OP_SET_MAX_LIFECYCLE, fragment, state));
return this;
}
void addOp(Op op) {
mOps.add(op);
op.mEnterAnim = mEnterAnim;
op.mExitAnim = mExitAnim;
op.mPopEnterAnim = mPopEnterAnim;
op.mPopExitAnim = mPopExitAnim;
}
每当做一个操作就会添加一个 Op
对象到 FragmentTransaction#mOps
成员变量中,操作分为很多种的类型,如下:
Java
static final int OP_NULL = 0;
static final int OP_ADD = 1; // 添加 Fragment
static final int OP_REPLACE = 2; // 替换 Container 中的 Fragment,旧的会被移除掉
static final int OP_REMOVE = 3; // 移除 Fragment
static final int OP_HIDE = 4; // 隐藏 Fragment
static final int OP_SHOW = 5; // 显示 Fragment
static final int OP_DETACH = 6; // DETACH Fragment
static final int OP_ATTACH = 7; // ATTACH Fragment
static final int OP_SET_PRIMARY_NAV = 8; // 将 Fragment 设置为 Primary
static final int OP_UNSET_PRIMARY_NAV = 9; // 将 Fragment 移除为 Primary
static final int OP_SET_MAX_LIFECYCLE = 10; // 设置 Fragment 的最大周期
关于设置生命周期的 OP
为啥叫设置最大的生命周期,我这里解释一下,因为 Fragment
的生命周期要受 FragmentManager
的生命周期的影响(在 Activity
中 FragmentManager
生命周期受 Activity
的生命周期影响)。假如当 FragmentManager
的生命周期为 Created
的时候,你想要 Fragment
生命周期为 Resume
时就不行,最多也是和 FragmentManager
一样为 Created
。只有当 FragmentManager
生命周期到 Resume
后,Fragment
才能够同步到达 Resume
。
在开始后面的内容前先说一下 Fragment
还有一种 PopBackStack
的操作方式(可能很多人都没有用过,也不怎么常用):
Kotlin
val tc = this@MyFragmentActivity.supportFragmentManager.beginTransaction()
tc.setMaxLifecycle(myFragments[FragmentType.A]!!, Lifecycle.State.CREATED)
tc.setReorderingAllowed(true)
tc.addToBackStack("test_stack")
tc.commitAllowingStateLoss()
当我想要对上面的提交操作,做相反的操作时,比如我上面是设置 Fragment
的生命周期为 CREATED
,我想要将 Fragment
生命周期设置为 DESTROYED
时,就只需要调用以下代码:
Kotlin
this@MyFragmentActivity.supportFragmentManager.popBackStack()
后面的代码阅读我会跳过 PopBackStack
相关的代码分析。
看看提交事务的 BackStackRecord#commitNowAllowingStateLoss()
方法:
Java
@Override
public void commitNowAllowingStateLoss() {
// commitNowXXX 相关的方法都禁止 BackStack
disallowAddToBackStack();
mManager.execSingleAction(this, true);
}
然后继续调用 FragmentManager#execSingleAction()
方法:
Java
void execSingleAction(@NonNull OpGenerator action, boolean allowStateLoss) {
if (allowStateLoss && (mHost == null || mDestroyed)) {
// This FragmentManager isn't attached, so drop the entire transaction.
return;
}
// 检查执行前的各种状态,也包括是否允许 StateLoss
ensureExecReady(allowStateLoss);
// 这个方法会将 Action 自己添加到 mTmpRecords 中,这个 Action 就是 FragmentTransaction
if (action.generateOps(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
try {
// 开始执行 FragmentTransaction
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
}
}
updateOnBackPressedCallbackEnabled();
doPendingDeferredStart();
mFragmentStore.burpActive();
}
继续看 FragmentManager#removeRedundantOperationsAndExecute()
方法:
Java
private void removeRedundantOperationsAndExecute(@NonNull ArrayList<BackStackRecord> records,
@NonNull ArrayList<Boolean> isRecordPop) {
if (records.isEmpty()) {
return;
}
if (records.size() != isRecordPop.size()) {
throw new IllegalStateException("Internal error with the back stack records");
}
final int numRecords = records.size();
int startIndex = 0;
for (int recordNum = 0; recordNum < numRecords; recordNum++) {
final boolean canReorder = records.get(recordNum).mReorderingAllowed;
if (!canReorder) {
// ...
// 执行 Records
executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
startIndex = reorderingEnd;
recordNum = reorderingEnd - 1;
}
}
if (startIndex != numRecords) {
executeOpsTogether(records, isRecordPop, startIndex, numRecords);
}
}
继续调用 executeOpsTogether()
:
Java
private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records,
@NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
// ...
// 展开 TC 中的 Op
for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
final BackStackRecord record = records.get(recordNum);
final boolean isPop = isRecordPop.get(recordNum);
if (!isPop) {
// 展开 TC 中的 Op
oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
} else {
// ...
}
// ...
}
// ...
// 确保 Op 中的 Fragment 都在 Active 的列表中
if (!allowReordering && mCurState >= Fragment.CREATED) {
// When reordering isn't allowed, we may be operating on Fragments that haven't
// been made active
for (int index = startIndex; index < endIndex; index++) {
BackStackRecord record = records.get(index);
for (FragmentTransaction.Op op : record.mOps) {
Fragment fragment = op.mFragment;
// 确保 Fragment 在 Active 的列表中
if (fragment != null && fragment.mFragmentManager != null) {
FragmentStateManager fragmentStateManager =
createOrGetFragmentStateManager(fragment);
mFragmentStore.makeActive(fragmentStateManager);
}
}
}
}
// 执行 Op 任务,更新各种 Fragment 中的数据
executeOps(records, isRecordPop, startIndex, endIndex);
// The last operation determines the overall direction, this ensures that operations
// such as push, push, pop, push are correctly considered a push
boolean isPop = isRecordPop.get(endIndex - 1);
// ...
// Ensure that Fragments directly affected by operations
// are moved to their expected state in operation order
// 更新 Fragment 的生命周期,和处理一些对应的事情
for (int index = startIndex; index < endIndex; index++) {
BackStackRecord record = records.get(index);
if (isPop) {
// ...
} else {
for (FragmentTransaction.Op op : record.mOps) {
Fragment fragment = op.mFragment;
if (fragment != null) {
FragmentStateManager fragmentStateManager =
createOrGetFragmentStateManager(fragment);
// 更新 Fragment 的生命周期,和处理一些对应的事情
fragmentStateManager.moveToExpectedState();
}
}
}
}
// And only then do we move all other fragments to the current state
moveToState(mCurState, true);
Set<SpecialEffectsController> changedControllers = collectChangedControllers(
records, startIndex, endIndex);
// 执行一些特殊任务,像动画什么的
for (SpecialEffectsController controller : changedControllers) {
controller.updateOperationDirection(isPop);
controller.markPostponedState();
controller.executePendingOperations();
}
// ...
}
简单理一下上面的方法做的事情:
- 展开
BackStackRecord
中的Op
,调用的方法是BackStackRecord#expandOps()
- 确保
Op
中的Fragment
都在Active
的列表中 - 通过
executeOps()
方法,执行Op
任务 - 更新
Fragment
的生命周期和处理一些对应的事情,对应的方法是FragmentStateManager#moveToExpectedState()
- 执行特殊任务,比如动画任务
再看看 BackStackRecord#expandOps()
是如何展开 Op
的:
Java
@SuppressWarnings("ReferenceEquality")
Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
for (int opNum = 0; opNum < mOps.size(); opNum++) {
final Op op = mOps.get(opNum);
switch (op.mCmd) {
case OP_ADD:
case OP_ATTACH:
added.add(op.mFragment);
break;
case OP_REMOVE:
case OP_DETACH: {
added.remove(op.mFragment);
if (op.mFragment == oldPrimaryNav) {
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.mFragment));
opNum++;
oldPrimaryNav = null;
}
}
break;
case OP_REPLACE: {
final Fragment f = op.mFragment;
final int containerId = f.mContainerId;
boolean alreadyAdded = false;
// 查找上次使用这个 containerId 的 Fragment
for (int i = added.size() - 1; i >= 0; i--) {
final Fragment old = added.get(i);
if (old.mContainerId == containerId) {
if (old == f) { // 上次的 Fragment 和当前 Fragment 是同一个
alreadyAdded = true;
} else { // 上次 Fragment 和当前的 Fragment 不是同一个
// This is duplicated from above since we only make
// a single pass for expanding ops. Unset any outgoing primary nav.
if (old == oldPrimaryNav) {
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, old, true));
opNum++;
oldPrimaryNav = null;
}
// 添加一个 Op 移除上次的 Fragment
final Op removeOp = new Op(OP_REMOVE, old, true);
removeOp.mEnterAnim = op.mEnterAnim;
removeOp.mPopEnterAnim = op.mPopEnterAnim;
removeOp.mExitAnim = op.mExitAnim;
removeOp.mPopExitAnim = op.mPopExitAnim;
mOps.add(opNum, removeOp);
added.remove(old);
opNum++;
}
}
}
if (alreadyAdded) {
// 移除当前的 OP_REPLACE 的 OP
mOps.remove(opNum);
opNum--;
} else {
// 修改当前的 OP_REPLACE 为 OP_ADD
op.mCmd = OP_ADD;
op.mFromExpandedOp = true;
added.add(f);
}
}
break;
case OP_SET_PRIMARY_NAV: {
// It's ok if this is null, that means we will restore to no active
// primary navigation fragment on a pop.
mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, oldPrimaryNav, true));
op.mFromExpandedOp = true;
opNum++;
// Will be set by the OP_SET_PRIMARY_NAV we inserted before when run
oldPrimaryNav = op.mFragment;
}
break;
}
}
return oldPrimaryNav;
}
展开 Op
主要干的事情是,当执行 OP_REPLACE
时,会去查找上次这个 ContainerId
所对应的 Fragment
,如果找到了就添加一个 OP_REMOVE
去移除这个 Fragment
,同时将 OP_REPLACE
修改为 OP_ADD
。
继续看 executeOps()
方法:
Java
private static void executeOps(@NonNull ArrayList<BackStackRecord> records,
@NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
for (int i = startIndex; i < endIndex; i++) {
final BackStackRecord record = records.get(i);
final boolean isPop = isRecordPop.get(i);
if (isPop) {
// ...
} else {
record.bumpBackStackNesting(1);
record.executeOps();
}
}
}
void executeOps() {
final int numOps = mOps.size();
for (int opNum = 0; opNum < numOps; opNum++) {
final Op op = mOps.get(opNum);
final Fragment f = op.mFragment;
if (f != null) {
f.mBeingSaved = mBeingSaved;
f.setPopDirection(false);
f.setNextTransition(mTransition);
f.setSharedElementNames(mSharedElementSourceNames, mSharedElementTargetNames);
}
switch (op.mCmd) {
case OP_ADD:
f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
mManager.setExitAnimationOrder(f, false);
// 将 Fragment 添加到 Active 和 Added 列表中
mManager.addFragment(f);
break;
case OP_REMOVE:
f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
// 将 Fragment 从 Added 列表中移除
mManager.removeFragment(f);
break;
case OP_HIDE:
f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
// 标记隐藏
mManager.hideFragment(f);
break;
case OP_SHOW:
f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
mManager.setExitAnimationOrder(f, false);
// 标记可见
mManager.showFragment(f);
break;
case OP_DETACH:
f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
// 将 Fragment 从 Added 列表中移除,同时标记 detach
mManager.detachFragment(f);
break;
case OP_ATTACH:
f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
mManager.setExitAnimationOrder(f, false);
// 将 Fragment 添加到 Added 列表中,同时标记 attach
mManager.attachFragment(f);
break;
case OP_SET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(f);
break;
case OP_UNSET_PRIMARY_NAV:
mManager.setPrimaryNavigationFragment(null);
break;
case OP_SET_MAX_LIFECYCLE:
// 更新最大的生命周期
mManager.setMaxLifecycle(f, op.mCurrentMaxState);
break;
default:
throw new IllegalArgumentException("Unknown cmd: " + op.mCmd);
}
}
}
上面的代码都很简单,就是简单更新 Added
和 Active
两个列表,和一些简单的数据。
接着看看 FragmentStateManager#moveToExpectedState()
方法,这个方法就涉及到 Fragment
的状态更新和生命周期方法的回调了。
Java
void moveToExpectedState() {
if (mMovingToState) {
if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
Log.v(FragmentManager.TAG, "Ignoring re-entrant call to "
+ "moveToExpectedState() for " + getFragment());
}
return;
}
try {
mMovingToState = true;
boolean stateWasChanged = false;
int newState;
// 计算本次循环的 Fragment 的期望的状态,如果不等于当前状态,执行循环
while ((newState = computeExpectedState()) != mFragment.mState) {
stateWasChanged = true;
if (newState > mFragment.mState) { // 生命周期向前更新,比如 Created -> Started
// Moving upward
int nextStep = mFragment.mState + 1;
switch (nextStep) {
case Fragment.ATTACHED:
attach();
break;
case Fragment.CREATED:
create();
break;
case Fragment.VIEW_CREATED:
ensureInflatedView();
createView();
break;
case Fragment.AWAITING_EXIT_EFFECTS:
activityCreated();
break;
case Fragment.ACTIVITY_CREATED:
if (mFragment.mView != null && mFragment.mContainer != null) {
SpecialEffectsController controller = SpecialEffectsController
.getOrCreateController(mFragment.mContainer,
mFragment.getParentFragmentManager());
int visibility = mFragment.mView.getVisibility();
SpecialEffectsController.Operation.State finalState =
SpecialEffectsController.Operation.State.from(visibility);
controller.enqueueAdd(finalState, this);
}
mFragment.mState = Fragment.ACTIVITY_CREATED;
break;
case Fragment.STARTED:
start();
break;
case Fragment.AWAITING_ENTER_EFFECTS:
mFragment.mState = Fragment.AWAITING_ENTER_EFFECTS;
break;
case Fragment.RESUMED:
resume();
break;
}
} else { // 生命周期向后更新,比如 Started -> Created
// Moving downward
int nextStep = mFragment.mState - 1;
switch (nextStep) {
case Fragment.AWAITING_ENTER_EFFECTS:
pause();
break;
case Fragment.STARTED:
mFragment.mState = Fragment.STARTED;
break;
case Fragment.ACTIVITY_CREATED:
stop();
break;
case Fragment.AWAITING_EXIT_EFFECTS:
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "movefrom ACTIVITY_CREATED: " + mFragment);
}
if (mFragment.mBeingSaved) {
mFragmentStore.setSavedState(mFragment.mWho, saveState());
} else if (mFragment.mView != null) {
// Need to save the current view state if not done already
// by saveInstanceState()
if (mFragment.mSavedViewState == null) {
saveViewState();
}
}
if (mFragment.mView != null && mFragment.mContainer != null) {
SpecialEffectsController controller = SpecialEffectsController
.getOrCreateController(mFragment.mContainer,
mFragment.getParentFragmentManager());
controller.enqueueRemove(this);
}
mFragment.mState = Fragment.AWAITING_EXIT_EFFECTS;
break;
case Fragment.VIEW_CREATED:
mFragment.mInLayout = false;
mFragment.mState = Fragment.VIEW_CREATED;
break;
case Fragment.CREATED:
destroyFragmentView();
mFragment.mState = Fragment.CREATED;
break;
case Fragment.ATTACHED:
if (mFragment.mBeingSaved
&& mFragmentStore.getSavedState(mFragment.mWho) == null) {
mFragmentStore.setSavedState(mFragment.mWho, saveState());
}
destroy();
break;
case Fragment.INITIALIZING:
detach();
break;
}
}
}
// ...
} finally {
mMovingToState = false;
}
}
在上面的方法中会通过 computeExpectedState()
方法去计算下次 Fragment
应该执行的生命周期状态,比如 FragmentManager
的状态是 RESUMED
,当前 Fragment
的 状态是 ATTACHED
,同时 Fragment
的最大生命周期状态是 RESUMED
,那么在循环中 Fragment
的生命周期状态会依次更新:CREATED
-> VIEW_CREATED
-> ACTIVITY_CREATED
-> STARTED
-> RESUME
。并执行相关 Fragment
的生命周期回调。
我上面的例子举的是生命周期变大的例子,当然也有生命周期变小的例子。
我们也根据生命周期变大和变小分别来看他们的状态更新。
生命周期变大
ATTACHED
FragmentStateManager#attach()
:
Java
void attach() {
// ...
mFragment.mHost = mFragment.mFragmentManager.getHost();
mFragment.mParentFragment = mFragment.mFragmentManager.getParent();
mDispatcher.dispatchOnFragmentPreAttached(mFragment, false);
mFragment.performAttach();
mDispatcher.dispatchOnFragmentAttached(mFragment, false);
}
Fragment#performAttach()
:
Java
void performAttach() {
for (OnPreAttachedListener listener: mOnPreAttachedListeners) {
listener.onPreAttached();
}
mOnPreAttachedListeners.clear();
mChildFragmentManager.attachController(mHost, createFragmentContainer(), this);
mState = ATTACHED;
mCalled = false;
// 回调生命周期
onAttach(mHost.getContext());
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onAttach()");
}
mFragmentManager.dispatchOnAttachFragment(this);
mChildFragmentManager.dispatchAttach();
}
CREATED
FragmentManager#create()
:
Java
void create() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "moveto CREATED: " + mFragment);
}
Bundle savedInstanceState = null;
if (mFragment.mSavedFragmentState != null) {
savedInstanceState = mFragment.mSavedFragmentState.getBundle(SAVED_INSTANCE_STATE_KEY);
}
if (!mFragment.mIsCreated) {
mDispatcher.dispatchOnFragmentPreCreated(mFragment, savedInstanceState, false);
mFragment.performCreate(savedInstanceState);
mDispatcher.dispatchOnFragmentCreated(mFragment, savedInstanceState, false);
} else {
// ...
}
}
Fragment#performCreate()
:
Java
void performCreate(Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
mState = CREATED;
mCalled = false;
if (Build.VERSION.SDK_INT >= 19) {
mLifecycleRegistry.addObserver(new LifecycleEventObserver() {
@Override
public void onStateChanged(@NonNull LifecycleOwner source,
@NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_STOP) {
if (mView != null) {
Api19Impl.cancelPendingInputEvents(mView);
}
}
}
});
}
// 生命周期回调
onCreate(savedInstanceState);
mIsCreated = true;
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onCreate()");
}
// 更新 Lifecycle 生命周期事件
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}
VIEW_CREATED
FragmentStateManager#createView()
:
Java
void createView() {
if (mFragment.mFromLayout) {
// This case is handled by ensureInflatedView(), so there's nothing
// else we need to do here.
return;
}
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "moveto CREATE_VIEW: " + mFragment);
}
Bundle savedInstanceState = null;
if (mFragment.mSavedFragmentState != null) {
savedInstanceState = mFragment.mSavedFragmentState.getBundle(SAVED_INSTANCE_STATE_KEY);
}
LayoutInflater layoutInflater = mFragment.performGetLayoutInflater(savedInstanceState);
ViewGroup container = null;
// 根据 containerId 找到对应的 ContainerView
if (mFragment.mContainer != null) {
container = mFragment.mContainer;
} else if (mFragment.mContainerId != 0) {
if (mFragment.mContainerId == View.NO_ID) {
throw new IllegalArgumentException("Cannot create fragment " + mFragment
+ " for a container view with no id");
}
FragmentContainer fragmentContainer = mFragment.mFragmentManager.getContainer();
container = (ViewGroup) fragmentContainer.onFindViewById(mFragment.mContainerId);
if (container == null) {
if (!mFragment.mRestored) {
String resName;
try {
resName = mFragment.getResources().getResourceName(mFragment.mContainerId);
} catch (Resources.NotFoundException e) {
resName = "unknown";
}
throw new IllegalArgumentException("No view found for id 0x"
+ Integer.toHexString(mFragment.mContainerId) + " ("
+ resName + ") for fragment " + mFragment);
}
} else {
if (!(container instanceof FragmentContainerView)) {
FragmentStrictMode.onWrongFragmentContainer(mFragment, container);
}
}
}
mFragment.mContainer = container;
// 执行 onCreateView() 生命周期
mFragment.performCreateView(layoutInflater, container, savedInstanceState);
if (mFragment.mView != null) { // 如果创建的 view 不为空
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "moveto VIEW_CREATED: " + mFragment);
}
mFragment.mView.setSaveFromParentEnabled(false);
// 将 Fragment 设置 tag 到 view 中
mFragment.mView.setTag(R.id.fragment_container_view_tag, mFragment);
if (container != null) {
// 将 view 添加到 container 中
addViewToContainer();
}
// 更新可见
if (mFragment.mHidden) {
mFragment.mView.setVisibility(View.GONE);
}
// How I wish we could use doOnAttach
if (ViewCompat.isAttachedToWindow(mFragment.mView)) {
ViewCompat.requestApplyInsets(mFragment.mView);
} else {
final View fragmentView = mFragment.mView;
fragmentView.addOnAttachStateChangeListener(
new View.OnAttachStateChangeListener() {
@Override
public void onViewAttachedToWindow(View v) {
fragmentView.removeOnAttachStateChangeListener(this);
ViewCompat.requestApplyInsets(fragmentView);
}
@Override
public void onViewDetachedFromWindow(View v) {
}
});
}
// 触发 onViewCreated() 生命周期回调
mFragment.performViewCreated();
mDispatcher.dispatchOnFragmentViewCreated(
mFragment, mFragment.mView, savedInstanceState, false);
int postOnViewCreatedVisibility = mFragment.mView.getVisibility();
float postOnViewCreatedAlpha = mFragment.mView.getAlpha();
mFragment.setPostOnViewCreatedAlpha(postOnViewCreatedAlpha);
if (mFragment.mContainer != null && postOnViewCreatedVisibility == View.VISIBLE) {
// Save the focused view if one was set via requestFocus()
View focusedView = mFragment.mView.findFocus();
if (focusedView != null) {
mFragment.setFocusedView(focusedView);
if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
Log.v(TAG, "requestFocus: Saved focused view " + focusedView
+ " for Fragment " + mFragment);
}
}
// Set the view alpha to 0
mFragment.mView.setAlpha(0f);
}
}
mFragment.mState = Fragment.VIEW_CREATED;
}
创建 View
的方法要稍微复杂一点点,首先通过 containerId
找到其对应的 containerView
;然后触发 Fragment#performCreateView()
方法创建 view
;将创建的 view
添加到 containerView
中;触发 Fragment#performViewCreated()
。
Fragment#performCreateView()
:
Java
void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
mPerformedCreateView = true;
mViewLifecycleOwner = new FragmentViewLifecycleOwner(this, getViewModelStore(),
() -> {
// Perform the restore as soon as the FragmentViewLifecycleOwner
// becomes initialized, to ensure it is always available
mViewLifecycleOwner.performRestore(mSavedViewRegistryState);
mSavedViewRegistryState = null;
});
// 触发生命周期创建 view
mView = onCreateView(inflater, container, savedInstanceState);
if (mView != null) {
// Initialize the view lifecycle
mViewLifecycleOwner.initialize();
// Tell the fragment's new view about it before we tell anyone listening
// to mViewLifecycleOwnerLiveData and before onViewCreated, so that calls to
// ViewTree get() methods return something meaningful
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(FragmentManager.TAG, "Setting ViewLifecycleOwner on View " + mView
+ " for Fragment " + this);
}
ViewTreeLifecycleOwner.set(mView, mViewLifecycleOwner);
ViewTreeViewModelStoreOwner.set(mView, mViewLifecycleOwner);
ViewTreeSavedStateRegistryOwner.set(mView, mViewLifecycleOwner);
// Then inform any Observers of the new LifecycleOwner
mViewLifecycleOwnerLiveData.setValue(mViewLifecycleOwner);
} else {
if (mViewLifecycleOwner.isInitialized()) {
throw new IllegalStateException("Called getViewLifecycleOwner() but "
+ "onCreateView() returned null");
}
mViewLifecycleOwner = null;
}
}
Fragment#performViewCreated()
:
Java
void performViewCreated() {
// since calling super.onViewCreated() is not required, we do not need to set and check the
// `mCalled` flag
Bundle savedInstanceState = null;
if (mSavedFragmentState != null) {
savedInstanceState = mSavedFragmentState.getBundle(
FragmentStateManager.SAVED_INSTANCE_STATE_KEY);
}
onViewCreated(mView, savedInstanceState);
mChildFragmentManager.dispatchViewCreated();
}
AWAITING_EXIT_EFFECTS
FragmentStateManager#activityCreated()
:
Java
void activityCreated() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "moveto ACTIVITY_CREATED: " + mFragment);
}
Bundle savedInstanceState = null;
if (mFragment.mSavedFragmentState != null) {
savedInstanceState = mFragment.mSavedFragmentState.getBundle(SAVED_INSTANCE_STATE_KEY);
}
mFragment.performActivityCreated(savedInstanceState);
mDispatcher.dispatchOnFragmentActivityCreated(
mFragment, savedInstanceState, false);
}
Fragment#performActivityCreated()
:
Java
void performActivityCreated(Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
mState = AWAITING_EXIT_EFFECTS;
mCalled = false;
onActivityCreated(savedInstanceState);
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onActivityCreated()");
}
restoreViewState();
mChildFragmentManager.dispatchActivityCreated();
}
STARTED
FragmentStateManager#start()
:
Java
void start() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "moveto STARTED: " + mFragment);
}
mFragment.performStart();
mDispatcher.dispatchOnFragmentStarted(mFragment, false);
}
Fragment#performStart()
:
Java
void performStart() {
mChildFragmentManager.noteStateNotSaved();
mChildFragmentManager.execPendingActions(true);
mState = STARTED;
mCalled = false;
onStart();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onStart()");
}
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_START);
if (mView != null) {
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_START);
}
mChildFragmentManager.dispatchStart();
}
RESUMED
FragmentStateManager#resume()
:
Java
void resume() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "moveto RESUMED: " + mFragment);
}
View focusedView = mFragment.getFocusedView();
if (focusedView != null && isFragmentViewChild(focusedView)) {
boolean success = focusedView.requestFocus();
if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
Log.v(FragmentManager.TAG, "requestFocus: Restoring focused view "
+ focusedView + " " + (success ? "succeeded" : "failed") + " on Fragment "
+ mFragment + " resulting in focused view " + mFragment.mView.findFocus());
}
}
mFragment.setFocusedView(null);
mFragment.performResume();
mDispatcher.dispatchOnFragmentResumed(mFragment, false);
mFragmentStore.setSavedState(mFragment.mWho, null);
mFragment.mSavedFragmentState = null;
mFragment.mSavedViewState = null;
mFragment.mSavedViewRegistryState = null;
}
Fragment#performResume()
:
Java
void performResume() {
mChildFragmentManager.noteStateNotSaved();
mChildFragmentManager.execPendingActions(true);
mState = RESUMED;
mCalled = false;
onResume();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onResume()");
}
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
if (mView != null) {
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_RESUME);
}
mChildFragmentManager.dispatchResume();
}
生命周期变小
AWAITING_ENTER_EFFECTS
FragmentStateManager#pause()
:
Java
void pause() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "movefrom RESUMED: " + mFragment);
}
mFragment.performPause();
mDispatcher.dispatchOnFragmentPaused(mFragment, false);
}
Fragment#performPause()
:
Java
void performPause() {
mChildFragmentManager.dispatchPause();
if (mView != null) {
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
}
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_PAUSE);
mState = AWAITING_ENTER_EFFECTS;
mCalled = false;
onPause();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onPause()");
}
}
ACTIVITY_CREATED
FragmentManagerState#stop()
:
Java
void stop() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "movefrom STARTED: " + mFragment);
}
mFragment.performStop();
mDispatcher.dispatchOnFragmentStopped(mFragment, false);
}
Fragment#performStop()
:
Java
void performStop() {
mChildFragmentManager.dispatchStop();
if (mView != null) {
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
}
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
mState = ACTIVITY_CREATED;
mCalled = false;
onStop();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onStop()");
}
}
CREATED
FragmentStateManager#destroyFragmentView()
:
Java
void destroyFragmentView() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "movefrom CREATE_VIEW: " + mFragment);
}
// In cases where we never got up to AWAITING_EXIT_EFFECTS, we
// need to manually remove the view from the container to reverse
// what we did in createView()
// 从 container 中移除 view
if (mFragment.mContainer != null && mFragment.mView != null) {
mFragment.mContainer.removeView(mFragment.mView);
}
mFragment.performDestroyView();
mDispatcher.dispatchOnFragmentViewDestroyed(mFragment, false);
mFragment.mContainer = null;
mFragment.mView = null;
// Set here to ensure that Observers are called after
// the Fragment's view is set to null
mFragment.mViewLifecycleOwner = null;
mFragment.mViewLifecycleOwnerLiveData.setValue(null);
mFragment.mInLayout = false;
}
Fragment#performDestoryView()
:
Java
void performDestroyView() {
mChildFragmentManager.dispatchDestroyView();
if (mView != null && mViewLifecycleOwner.getLifecycle().getCurrentState()
.isAtLeast(Lifecycle.State.CREATED)) {
mViewLifecycleOwner.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
}
mState = CREATED;
mCalled = false;
onDestroyView();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onDestroyView()");
}
// Handles the detach/reattach case where the view hierarchy
// is destroyed and recreated and an additional call to
// onLoadFinished may be needed to ensure the new view
// hierarchy is populated from data from the Loaders
LoaderManager.getInstance(this).markForRedelivery();
mPerformedCreateView = false;
}
ATTACHED
FragmentStateManager#destroy()
:
Java
void destroy() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "movefrom CREATED: " + mFragment);
}
boolean beingRemoved = mFragment.mRemoving && !mFragment.isInBackStack();
// Clear any previous saved state
if (beingRemoved && !mFragment.mBeingSaved) {
mFragmentStore.setSavedState(mFragment.mWho, null);
}
boolean shouldDestroy = beingRemoved
|| mFragmentStore.getNonConfig().shouldDestroy(mFragment);
if (shouldDestroy) {
FragmentHostCallback<?> host = mFragment.mHost;
boolean shouldClear;
if (host instanceof ViewModelStoreOwner) {
shouldClear = mFragmentStore.getNonConfig().isCleared();
} else if (host.getContext() instanceof Activity) {
Activity activity = (Activity) host.getContext();
shouldClear = !activity.isChangingConfigurations();
} else {
shouldClear = true;
}
if ((beingRemoved && !mFragment.mBeingSaved) || shouldClear) {
// 移除 Fragment 中的 ViewModelStore
mFragmentStore.getNonConfig().clearNonConfigState(mFragment);
}
// 销毁
mFragment.performDestroy();
mDispatcher.dispatchOnFragmentDestroyed(mFragment, false);
// Ensure that any Fragment that had this Fragment as its
// target Fragment retains a reference to the Fragment
for (FragmentStateManager fragmentStateManager :
mFragmentStore.getActiveFragmentStateManagers()) {
if (fragmentStateManager != null) {
Fragment fragment = fragmentStateManager.getFragment();
if (mFragment.mWho.equals(fragment.mTargetWho)) {
fragment.mTarget = mFragment;
fragment.mTargetWho = null;
}
}
}
if (mFragment.mTargetWho != null) {
// Restore the target Fragment so that it can be accessed
// even after the Fragment is removed.
mFragment.mTarget = mFragmentStore.findActiveFragment(mFragment.mTargetWho);
}
// 将 Fragment 从 Attach 列表中移除
mFragmentStore.makeInactive(this);
} else {
if (mFragment.mTargetWho != null) {
Fragment target = mFragmentStore.findActiveFragment(mFragment.mTargetWho);
if (target != null && target.mRetainInstance) {
// Only keep references to other retained Fragments
// to avoid developers accessing Fragments that
// are never coming back
mFragment.mTarget = target;
}
}
mFragment.mState = Fragment.ATTACHED;
}
}
上面代码中首先将 Fragment
中的 ViewModelStore
移除,还包括其他的 NonConfig
数据;然后回调 Fragment#performDestroy()
;最后将被销毁的 Fragment
从 Active
列表中移除。
Fragment#performDestroy()
:
Java
void performDestroy() {
mChildFragmentManager.dispatchDestroy();
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_DESTROY);
mState = ATTACHED;
mCalled = false;
mIsCreated = false;
onDestroy();
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onDestroy()");
}
}
INITIALIZING
FragmentStateManager#detach()
:
Java
void detach() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "movefrom ATTACHED: " + mFragment);
}
mFragment.performDetach();
mDispatcher.dispatchOnFragmentDetached(
mFragment, false);
mFragment.mState = Fragment.INITIALIZING;
mFragment.mHost = null;
mFragment.mParentFragment = null;
mFragment.mFragmentManager = null;
boolean beingRemoved = mFragment.mRemoving && !mFragment.isInBackStack();
if (beingRemoved || mFragmentStore.getNonConfig().shouldDestroy(mFragment)) {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "initState called for fragment: " + mFragment);
}
mFragment.initState();
}
}
Fragment#performDetach()
:
Java
void performDetach() {
mState = INITIALIZING;
mCalled = false;
onDetach();
mLayoutInflater = null;
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onDetach()");
}
// Destroy the child FragmentManager if we still have it here.
// This is normally done in performDestroy(), but is done here
// specifically if the Fragment is retained.
// 销毁并清空 FragmentManager
if (!mChildFragmentManager.isDestroyed()) {
mChildFragmentManager.dispatchDestroy();
mChildFragmentManager = new FragmentManagerImpl();
}
}
最后
到这里我的 Fragment
的源码阅读就结束了,但是还有很多的功能细节我没有涉及,如果你还感兴趣,就自行去看了,希望我的文章能够帮助到你。