基本使用

Fragment的使用一般涉及到两个类:FragmentManagerFragmentTransaction

1
2
val fragmentManager = supportFragmentManager
val fragmentTransaction = fragmentManager.beginTransaction()

可使用 FragmentManager 执行的操作包括:

  • 通过 findFragmentById()findFragmentByTag()获取 Activity 中存在的片段。
  • 通过 popBackStack()(模拟用户发出的返回命令)使片段从返回栈中弹出。
  • 通过 addOnBackStackChangedListener() 注册侦听返回栈变化的侦听器。

可以从 FragmentManager 获取一个 FragmentTransaction 实例,然后使用 add()remove()replace() 等方法,为给定事务设置您想要执行的所有更改。然后,如要将事务应用到 Activity,您必须调用 commit()

1
2
3
4
5
val newFragment = ExampleFragment()
val transaction = supportFragmentManager.beginTransaction()
transaction.replace(R.id.fragment_container, newFragment)
transaction.addToBackStack(null)
transaction.commit()

源码分析

FragmentController

MainActivity:AppCompatActivity:FragmentActivity。在FragmentActivity中有一个常量叫mFragments。

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

这是一个FragmentController对象。FragmentController,听名字是一个控制类,看来应该是用来控制Fragment的,其内部持有一个FragmentHostCallback类型的对象mHost。

1
2
3
4
5
6
7
8
9
10
11
12
public class FragmentController {
private final FragmentHostCallback<?> mHost;
...
//下面都是类似这样的代码:
public XX FunXX () {
return mHost.mFragmentManager.FunXX();
}
//比如:
public void attachHost(@Nullable Fragment parent) {
mHost.mFragmentManager.attachController(mHost, mHost /*container*/, parent);
}
}

扫一眼这个控制类下面的方法,基本上都是调用的mHost.mFragmentManager.XX( )方法,所以我们判断FragmentController类又是个空壳子,其类目的方法全在mHost的mFragmentManager对象中实现。

所以我们理所当然的打开FragmentHostCallback,发现里面持有这样几个对象。

1
2
3
4
5
6
7
8
public abstract class FragmentHostCallback<E> extends FragmentContainer {
private final Activity mActivity;
private final Context mContext;
private final Handler mHandler;
private final int mWindowAnimations;
final FragmentManager mFragmentManager = new FragmentManagerImpl();
...
}

FragmentManager是个常量,我们没有调用任何代码ta就在这里自己创建了。得到这个信息就够了,然后我们看自己调用的代码。

wait…

对了,还有一个地方要看一眼,在FragmentActivity的onCreate方法中,有一行mFragments.attachHost(null /parent/);去到FragmentManager中看:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
void attachController(@NonNull FragmentHostCallback<?> host,
@NonNull FragmentContainer container, @Nullable final Fragment parent) {
if (mHost != null) throw new IllegalStateException("Already attached");
mHost = host;
mContainer = container;
mParent = parent;
if (mParent != null) {
// Since the callback depends on us being the primary navigation fragment,
// update our callback now that we have a parent so that we have the correct
// state by default
updateOnBackPressedCallbackEnabled();
}
// Set up the OnBackPressedCallback
if (host instanceof OnBackPressedDispatcherOwner) {
OnBackPressedDispatcherOwner dispatcherOwner = ((OnBackPressedDispatcherOwner) host);
mOnBackPressedDispatcher = dispatcherOwner.getOnBackPressedDispatcher();
LifecycleOwner owner = parent != null ? parent : dispatcherOwner;
mOnBackPressedDispatcher.addCallback(owner, mOnBackPressedCallback);
}

// Get the FragmentManagerViewModel
if (parent != null) {
mNonConfig = parent.mFragmentManager.getChildNonConfig(parent);
} else if (host instanceof ViewModelStoreOwner) {
ViewModelStore viewModelStore = ((ViewModelStoreOwner) host).getViewModelStore();
mNonConfig = FragmentManagerViewModel.getInstance(viewModelStore);
} else {
mNonConfig = new FragmentManagerViewModel(false);
}
}

给FragmentManager传了一些值进去,包括mHost,mParent等。mHost就是FragmentHostCallback。

FragmentManager

好了,现在我们自己在调用getSupportFragmentManager()方法时,返回的就是我们刚刚看到的mFragmentManager,也是创建FragmentControl时带入的HostCallbacks。

1
2
3
4
5
6
7
8
//-----------FragmentActivity.java-------------
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
//-----------FragmentControl.java-----------------
public FragmentManager getSupportFragmentManager() {
return mHost.mFragmentManager;
}

所以beginTransaction自然要去FragmentManager类下面去找了。

beginTransaction

1
2
3
4
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);//this就是FragmentManager呐。
}

BackStackRecord继承FragmentTransaction,FragmentTransaction是一个抽象类。

1
2
3
final class BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry, FragmentManager.OpGenerator {
...
}

所以我们一般调用add、show、hide、replace等操作时,实际是调用的FragmentTransaction中的方法。以add方法为例:

add(containerViewId,fragment)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
public abstract class FragmentTransaction {
public FragmentTransaction add(@IdRes int containerViewId, @NonNull Fragment fragment) {
doAddOp(containerViewId, fragment, null, OP_ADD);
return this;
}

void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
final Class<?> fragmentClass = fragment.getClass();
final int modifiers = fragmentClass.getModifiers();
if (fragmentClass.isAnonymousClass() || !Modifier.isPublic(modifiers)
|| (fragmentClass.isMemberClass() && !Modifier.isStatic(modifiers))) {
throw new IllegalStateException("Fragment " + fragmentClass.getCanonicalName()
+ " must be a public static class to be properly recreated from"
+ " instance state.");
}

if (tag != null) {
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;
}

//---------------------存储containerViewId到fragment中--------------
if (containerViewId != 0) {
if (containerViewId == View.NO_ID) {
throw new IllegalArgumentException("Can't add fragment "
+ fragment + " with tag " + tag + " to container view with no id");
}
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;
}

addOp(new Op(opcmd, fragment));
}

ArrayList<Op> mOps = new ArrayList<>();
void addOp(Op op) {
mOps.add(op);
op.mEnterAnim = mEnterAnim;
op.mExitAnim = mExitAnim;
op.mPopEnterAnim = mPopEnterAnim;
op.mPopExitAnim = mPopExitAnim;
}

public abstract int commit();
}

校验完合法性后,做了两件事:

  1. 将containerViewId存入到fragment中的mContainerId 和 mFragmentId;

  2. addOp()传入的是一个Op对象,包含标记opcmd和fragment。op对象随后被添加到一个叫mOps的队列中。

看来关键代码在commit身上,所以我们每次用Fragment的时候忘记调用commit就会看不到界面变化。

commit

commit是个抽象方法,其实现在BackStackRecord中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
final class BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry, FragmentManager.OpGenerator {
@Override
public int commit() {
return commitInternal(false);
}

int commitInternal(boolean allowStateLoss) {
if (mCommitted) throw new IllegalStateException("commit already called");
if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
Log.v(TAG, "Commit: " + this);
LogWriter logw = new LogWriter(TAG);
PrintWriter pw = new PrintWriter(logw);
dump(" ", pw);
pw.close();
}
mCommitted = true;
if (mAddToBackStack) {
mIndex = mManager.allocBackStackIndex();
} else {
mIndex = -1;
}
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
}

mAddToBackStack表示是否加入返回栈,是的话就从manager中返回一个index,表示当前栈中第几个fragment,否则返回-1。

重点方法在enqueueAction中:

enqueueAction

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
private final ArrayList<OpGenerator> mPendingActions = new ArrayList<>();

void enqueueAction(@NonNull OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
//不允许状态改变
if (mHost == null) {
if (mDestroyed) {
throw new IllegalStateException("FragmentManager has been destroyed");
} else {
throw new IllegalStateException("FragmentManager has not been attached to a "
+ "host.");
}
}
checkStateLoss();//如果已经改变,就在在这个方法内抛错
}
synchronized (mPendingActions) {
if (mHost == null) {
if (allowStateLoss) {
// This FragmentManager isn't attached, so drop the entire transaction.
return;
}
throw new IllegalStateException("Activity has been destroyed");
}
mPendingActions.add(action);
scheduleCommit();
}
}

void scheduleCommit() {
synchronized (mPendingActions) {
boolean postponeReady =
mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
boolean pendingReady = mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
mHost.getHandler().removeCallbacks(mExecCommit);
mHost.getHandler().post(mExecCommit);
updateOnBackPressedCallbackEnabled();
}
}
}

private Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions(true);
}
};

做了三件事:1. 如果不允许状态改变则要做一些检查;

  1. 将action加入mPendingActions队列中;

  2. scheduleCommit

    3.1 (校验判断后)通过Handler将mExecCommit发送出去;

    3.2 处理是否拦截返回事件相关事务【通过返回栈的数目等信息判断】

我们在一开始的时候提到FragmentActivity的onCreate方法中有用到Manager.attachController(),mHost就是传进来的FragmentHostCallback对象。而mHandle是在其构造方法中就已被创建了。

这里用Handle是为了切换到主线程。我们直接关注mExecCommit中的execPendingActions方法就好:

execPendingActions

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
boolean execPendingActions(boolean allowStateLoss) {
//准备操作,初始化mTmpRecords,mTmpIsPop等
ensureExecReady(allowStateLoss);

boolean didSomething = false;
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
try {
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
}
didSomething = true;
}

updateOnBackPressedCallbackEnabled();
doPendingDeferredStart();
mFragmentStore.burpActive();

return didSomething;
}

generateOpsForPendingActions 循环条件

首先看while中的generateOpsForPendingActions:其大致做的事是,遍历完mPendingActions数组,为数组中每个OpGenerator执行generateOps方法。然后清空数组。操作成功返回true,否则【包括数组为null的情况】返回false,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
private boolean generateOpsForPendingActions(@NonNull ArrayList<BackStackRecord> records,
@NonNull ArrayList<Boolean> isPop) {
boolean didSomething = false;
synchronized (mPendingActions) {
if (mPendingActions.isEmpty()) {
return false;
}

final int numActions = mPendingActions.size();
for (int i = 0; i < numActions; i++) {
didSomething |= mPendingActions.get(i).generateOps(records, isPop);
}
mPendingActions.clear();
mHost.getHandler().removeCallbacks(mExecCommit);
}
return didSomething;
}

而在generateOps方法中,分别向records和isRecordPop中填充元素。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//----------------------BackStackRecord.java下--------------
@Override
public boolean generateOps(@NonNull ArrayList<BackStackRecord> records,
@NonNull ArrayList<Boolean> isRecordPop) {
if (FragmentManager.isLoggingEnabled(Log.VERBOSE)) {
Log.v(TAG, "Run: " + this);
}

records.add(this);
isRecordPop.add(false);
if (mAddToBackStack) {
mManager.addBackStackState(this);
}
return true;
}

综上,整个generateOpsForPendingActions的作用就是将mPendingActions中所有的记录添加到了records数组中。

removeRedundantOperationsAndExecute 循环内部

再看循环内部的removeRedundantOperationsAndExecute方法。先猜想一波,刚刚向数组中添加了元素,现在应该操作这些元素了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
//之前的版本中这个方法名叫 optimizeAndExecuteOps
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");
}

// Force start of any postponed transactions that interact with scheduled transactions:
//强制启动所有 与计划的transactions交互的 延迟的 transactions。即完成以前已延迟但现在已准备好的事务的transactions
executePostponedTransaction(records, isRecordPop);

final int numRecords = records.size();
int startIndex = 0;
for (int recordNum = 0; recordNum < numRecords; recordNum++) {
// 标记是否支持操作排序优化,默认为false
final boolean canReorder = records.get(recordNum).mReorderingAllowed;
if (!canReorder) {
// execute all previous transactions
if (startIndex != recordNum) {
executeOpsTogether(records, isRecordPop, startIndex, recordNum);
}
// execute all pop operations that don't allow reordering together or
// one add operation
int reorderingEnd = recordNum + 1;
// 非pop事务都返回false
if (isRecordPop.get(recordNum)) {
while (reorderingEnd < numRecords
&& isRecordPop.get(reorderingEnd)
&& !records.get(reorderingEnd).mReorderingAllowed) {
reorderingEnd++;
}
}
executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
startIndex = reorderingEnd;
recordNum = reorderingEnd - 1;
}
}
if (startIndex != numRecords) {
// 开启操作排序优化情况下可能会满足该if条件
executeOpsTogether(records, isRecordPop, startIndex, numRecords);
}
}

之前的版本中这个方法名叫 optimizeAndExecuteOps【优化并执行】,现在叫removeRedundantOperationsAndExecute【删除冗余操作并执行】。从命名可以看出Google开发团队对这个方法做出的解释–当有多个待执行事务时,FragmentManager会删除部分冗余事务操作。例如:

  • 假设有两个事务对同一布局容器一起执行,一个事务添加了一个 Fragment A,下一个事务将其替换为 Fragment B。则优化后会将第一个操作取消,仅添加 Fragment B。
  • 假设有三个事务,一个事务添加了 Fragment A,第二个事务添加了 Fragment B,然后第三个删除了 Fragment A。那么优化后将不会执行 Fragment A的添加和删除,仅添加 Fragment B。

排序优化操作会导致出现超出开发者预期的行为,因此默认不进行此操作。

参考博客:https://juejin.cn/post/6844904090485391368

实际实现的代码时executeOpsTogether()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records,
@NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
final boolean allowReordering = records.get(startIndex).mReorderingAllowed;
boolean addToBackStack = false;
if (mTmpAddedFragments == null) {
mTmpAddedFragments = new ArrayList<>();
} else {
mTmpAddedFragments.clear();
}
mTmpAddedFragments.addAll(mFragmentStore.getFragments());
Fragment oldPrimaryNav = getPrimaryNavigationFragment();
for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
final BackStackRecord record = records.get(recordNum);
final boolean isPop = isRecordPop.get(recordNum);
if (!isPop) {
oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
} else {
oldPrimaryNav = record.trackAddedFragmentsInPop(mTmpAddedFragments, oldPrimaryNav);
}
addToBackStack = addToBackStack || record.mAddToBackStack;
}
mTmpAddedFragments.clear();

if (!allowReordering) {
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex,
false, mFragmentTransitionCallback);
}
executeOps(records, isRecordPop, startIndex, endIndex);

int postponeIndex = endIndex;
if (allowReordering) {
ArraySet<Fragment> addedFragments = new ArraySet<>();
addAddedFragments(addedFragments);
postponeIndex = postponePostponableTransactions(records, isRecordPop,
startIndex, endIndex, addedFragments);
makeRemovedFragmentsInvisible(addedFragments);
}

if (postponeIndex != startIndex && allowReordering) {
// need to run something now
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
postponeIndex, true, mFragmentTransitionCallback);
moveToState(mCurState, true);
}

for (int recordNum = startIndex; recordNum < endIndex; recordNum++) {
final BackStackRecord record = records.get(recordNum);
final boolean isPop = isRecordPop.get(recordNum);
if (isPop && record.mIndex >= 0) {
record.mIndex = -1;
}
record.runOnCommitRunnables();
}
if (addToBackStack) {
reportBackStackChanged();
}
}
executeOps(records, isRecordPop, startIndex, endIndex);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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) {
record.bumpBackStackNesting(-1);
// Only execute the add operations at the end of
// all transactions.
boolean moveToState = i == (endIndex - 1);
record.executePopOps(moveToState);
} else {
record.bumpBackStackNesting(1);
record.executeOps();
}
}
}

record.executeOps()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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.setNextTransition(mTransition);
}
switch (op.mCmd) {
case OP_ADD:
f.setNextAnim(op.mEnterAnim);
mManager.setExitAnimationOrder(f, false);
mManager.addFragment(f);
break;
case OP_REMOVE:
f.setNextAnim(op.mExitAnim);
mManager.removeFragment(f);
break;
case OP_HIDE:
f.setNextAnim(op.mExitAnim);
mManager.hideFragment(f);
break;
case OP_SHOW:
f.setNextAnim(op.mEnterAnim);
mManager.setExitAnimationOrder(f, false);
mManager.showFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.mExitAnim);
mManager.detachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.mEnterAnim);
mManager.setExitAnimationOrder(f, false);
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);
}
if (!mReorderingAllowed && op.mCmd != OP_ADD && f != null) {
mManager.moveFragmentToExpectedState(f);
}
}
if (!mReorderingAllowed) {
// Added fragments are added at the end to comply with prior behavior.
mManager.moveToState(mManager.mCurState, true);
}
}

在这里根据不同的命令,执行不同的操作。最后MoveToState。

MoveToState(int,boolean)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
void moveToState(int newState, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}

if (!always && newState == mCurState) {
return;
}

mCurState = newState;

// Must add them in the proper order. mActive fragments may be out of order
for (Fragment f : mFragmentStore.getFragments()) {
moveFragmentToExpectedState(f);
}

// Now iterate through all active fragments. These will include those that are removed
// and detached.
for (Fragment f : mFragmentStore.getActiveFragments()) {
if (f != null && !f.mIsNewlyAdded) {
moveFragmentToExpectedState(f);
}
}

startPendingDeferredFragments();

if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
mHost.onSupportInvalidateOptionsMenu();
mNeedMenuInvalidate = false;
}
}

最终把Fragment展示出来实现的方法是moveFragemtnTOExpectedState(f);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
void moveFragmentToExpectedState(@NonNull Fragment f) {
if (!mFragmentStore.containsActiveFragment(f.mWho)) {
if (isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "Ignoring moving " + f + " to state " + mCurState
+ "since it is not added to " + this);
}
return;
}
moveToState(f);

if (f.mView != null) {
// Move the view if it is out of order
Fragment underFragment = mFragmentStore.findFragmentUnder(f);
if (underFragment != null) {
final View underView = underFragment.mView;
// make sure this fragment is in the right order.
final ViewGroup container = f.mContainer;
int underIndex = container.indexOfChild(underView);
int viewIndex = container.indexOfChild(f.mView);
if (viewIndex < underIndex) {
container.removeViewAt(viewIndex);
container.addView(f.mView, underIndex);
}
}
if (f.mIsNewlyAdded && f.mContainer != null) {
// Make it visible and run the animations
if (f.mPostponedAlpha > 0f) {
f.mView.setAlpha(f.mPostponedAlpha);
}
f.mPostponedAlpha = 0f;
f.mIsNewlyAdded = false;
// run animations:
FragmentAnim.AnimationOrAnimator anim = FragmentAnim.loadAnimation(
mHost.getContext(), mContainer, f, true);
if (anim != null) {
if (anim.animation != null) {
f.mView.startAnimation(anim.animation);
} else {
anim.animator.setTarget(f.mView);
anim.animator.start();
}
}
}
}
if (f.mHiddenChanged) {
completeShowHideFragment(f);
}
}

void moveToState(@NonNull Fragment f) {
moveToState(f, mCurState);
}

跟着这个moveToState(Fragment,int)才是主角:在生命周期的每个阶段要做什么,都写的很清楚。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
void moveToState(@NonNull Fragment f, int newState) {
FragmentStateManager fragmentStateManager = mFragmentStore.getFragmentStateManager(f.mWho);
if (fragmentStateManager == null) {
// Ideally, we only call moveToState() on active Fragments. However,
// in restoreSaveState() we can call moveToState() on retained Fragments
// just to clean them up without them ever being added to mActive.
// For these cases, a brand new FragmentStateManager is enough.
fragmentStateManager = new FragmentStateManager(mLifecycleCallbacksDispatcher, f);
// Only allow this FragmentStateManager to go up to CREATED at the most
fragmentStateManager.setFragmentManagerState(Fragment.CREATED);
}
newState = Math.min(newState, fragmentStateManager.computeMaxState());
if (f.mState <= newState) {
// If we are moving to the same state, we do not need to give up on the animation.
if (f.mState < newState && !mExitAnimationCancellationSignals.isEmpty()) {
// The fragment is currently being animated... but! Now we
// want to move our state back up. Give up on waiting for the
// animation and proceed from where we are.
cancelExitAnimation(f);
}
switch (f.mState) {
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {
if (isLoggingEnabled(Log.DEBUG)) Log.d(TAG, "moveto ATTACHED: " + f);

// If we have a target fragment, push it along to at least CREATED
// so that this one can rely on it as an initialized dependency.
if (f.mTarget != null) {
if (!f.mTarget.equals(findActiveFragment(f.mTarget.mWho))) {
throw new IllegalStateException("Fragment " + f
+ " declared target fragment " + f.mTarget
+ " that does not belong to this FragmentManager!");
}
if (f.mTarget.mState < Fragment.CREATED) {
moveToState(f.mTarget, Fragment.CREATED);
}
f.mTargetWho = f.mTarget.mWho;
f.mTarget = null;
}
if (f.mTargetWho != null) {
Fragment target = findActiveFragment(f.mTargetWho);
if (target == null) {
throw new IllegalStateException("Fragment " + f
+ " declared target fragment " + f.mTargetWho
+ " that does not belong to this FragmentManager!");
}
if (target.mState < Fragment.CREATED) {
moveToState(target, Fragment.CREATED);
}
}

fragmentStateManager.attach(mHost, this, mParent);
}
// fall through
case Fragment.ATTACHED:
if (newState > Fragment.ATTACHED) {
fragmentStateManager.create();
}
// fall through
case Fragment.CREATED:
// We want to unconditionally run this anytime we do a moveToState that
// moves the Fragment above INITIALIZING, including cases such as when
// we move from CREATED => CREATED as part of the case fall through above.
if (newState > Fragment.INITIALIZING) {
fragmentStateManager.ensureInflatedView();
}

if (newState > Fragment.CREATED) {
fragmentStateManager.createView(mContainer);
fragmentStateManager.activityCreated();
fragmentStateManager.restoreViewState();
}
// fall through
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {
fragmentStateManager.start();
}
// fall through
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
fragmentStateManager.resume();
}
}
} else if (f.mState > newState) {
....
}

if (f.mState != newState) {
if (isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "moveToState: Fragment state for " + f + " not updated inline; "
+ "expected state " + newState + " found " + f.mState);
}
f.mState = newState;
}
}

所以就会按顺序执行FragmentStateManager的attach–create—createView–activityCreated–start–resume方法。

以FragmentManager中的attach方法和create方法为例:

FragementManager-attach/create

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void attach(@NonNull FragmentHostCallback<?> host, @NonNull FragmentManager fragmentManager,
@Nullable Fragment parentFragment) {
mFragment.mHost = host;
mFragment.mParentFragment = parentFragment;
mFragment.mFragmentManager = fragmentManager;
mDispatcher.dispatchOnFragmentPreAttached(
mFragment, host.getContext(), false);
mFragment.performAttach();
if (mFragment.mParentFragment == null) {
host.onAttachFragment(mFragment);
} else {
mFragment.mParentFragment.onAttachFragment(mFragment);
}
mDispatcher.dispatchOnFragmentAttached(
mFragment, host.getContext(), false);
}

void create() {
if (FragmentManager.isLoggingEnabled(Log.DEBUG)) {
Log.d(TAG, "moveto CREATED: " + mFragment);
}
if (!mFragment.mIsCreated) {
mDispatcher.dispatchOnFragmentPreCreated(
mFragment, mFragment.mSavedFragmentState, false);
mFragment.performCreate(mFragment.mSavedFragmentState);
mDispatcher.dispatchOnFragmentCreated(
mFragment, mFragment.mSavedFragmentState, false);
} else {
mFragment.restoreChildFragmentState(mFragment.mSavedFragmentState);
mFragment.mState = Fragment.CREATED;
}
}

最后会调用到performAttach/performCreate方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
void performAttach() {
mChildFragmentManager.attachController(mHost, new FragmentContainer() {
@Override
@Nullable
public View onFindViewById(int id) {
if (mView == null) {
throw new IllegalStateException("Fragment " + this + " does not have a view");
}
return mView.findViewById(id);
}

@Override
public boolean onHasView() {
return (mView != null);
}
}, this);
mState = ATTACHED;
mCalled = false;
onAttach(mHost.getContext());
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onAttach()");
}
}

void performCreate(Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
mState = CREATED;
mCalled = false;
mSavedStateRegistryController.performRestore(savedInstanceState);
onCreate(savedInstanceState);
mIsCreated = true;
if (!mCalled) {
throw new SuperNotCalledException("Fragment " + this
+ " did not call through to super.onCreate()");
}
mLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
}

最后终于调用到了我们自己重写的的onAttach/onCreate方法里面。

最后来张图:

image-20210103151047522