- 本次分析Fragment 1.3.4版本刻像,不同版本源碼會(huì)不同!
- Fragment官方文檔
dependencies {
val fragment_version = "1.3.4"
// Java language implementation
implementation("androidx.fragment:fragment:$fragment_version")
// Kotlin
implementation("androidx.fragment:fragment-ktx:$fragment_version")
// Testing Fragments in Isolation
debugImplementation("androidx.fragment:fragment-testing:$fragment_version")
}
-
Fragment 無論是單獨(dú)使用還是配合Viewpager杈曲,對(duì)于Android開發(fā)來說非常熟悉了楞艾,但生命周期,一般就網(wǎng)上看到的一張圖,想必大家也經(jīng)常看到;
Fragment lifecyclee - 那Fragment的生命周期在什么時(shí)候調(diào)用的摩钙,commit之后怎么走到生命周期的每一個(gè)方法,需要看源碼才知道查辩,本文就此分析胖笛。
1.supportFragmentManager
- 只有使用 FragmentActivity 才有 supportFragmentManager 。
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.test_activity3_activity)
if (savedInstanceState == null) {
supportFragmentManager.beginTransaction()
.replace(R.id.container, TestActivity3Fragment.newInstance())
.commitNow()
}
}
1.1 getSupportFragmentManager
- FragmentActivity里面的 mFragments 可不是Fragment數(shù)組哦宜岛,他是 FragmentController 长踊,這個(gè)很重要,先記住他萍倡。
/* FragmentActivity類 */
//創(chuàng)建FragmentController
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
/**
* Return the FragmentManager for interacting with fragments associated
* with this activity.
*/
@NonNull
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
1.2 FragmentController類
- new HostCallbacks() 傳進(jìn)去身弊,再獲取 SupportFragmentManager。
public class FragmentController {
private final FragmentHostCallback<?> mHost;
/**
* Returns a {@link FragmentController}.
*/
@NonNull
public static FragmentController createController(@NonNull FragmentHostCallback<?> callbacks) {
return new FragmentController(checkNotNull(callbacks, "callbacks == null"));
}
private FragmentController(FragmentHostCallback<?> callbacks) {
mHost = callbacks;
}
/**
* 通過mHost獲取FragmentManager
* Returns a {@link FragmentManager} for this controller.
*/
@NonNull
public FragmentManager getSupportFragmentManager() {
return mHost.mFragmentManager;
}
}
1.3 FragmentHostCallback類
- FragmentHostCallback 里獲取 mFragmentManager列敲。
- FragmentManagerImpl 繼承FragmentManager阱佛,但什么都沒做。
public abstract class FragmentHostCallback<E> extends FragmentContainer {
@Nullable private final Activity mActivity;
@NonNull private final Context mContext;
@NonNull private final Handler mHandler;
private final int mWindowAnimations;
final FragmentManager mFragmentManager = new FragmentManagerImpl();
}
//繼承FragmentManager戴而,但什么都沒做
class FragmentManagerImpl extends FragmentManager {
}
- 到此就獲取一個(gè)fragmentManager凑术。
2.beginTransaction
- 每次處理Fragment的事務(wù)都是新建一個(gè) BackStackRecord 回退棧 ,只能用一次填硕。
@NonNull
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
2.1 FragmentTransaction類
- BackStackRecord 類是繼承 抽象類FragmentTransaction麦萤,這里有非常重要的各個(gè)OP常量,還有內(nèi)部類OP扁眯。
- add,hide,remove等操作也是在這個(gè)類,他們都會(huì)封裝進(jìn)Op翅帜,用數(shù)組mOps 保存姻檀。
public abstract class FragmentTransaction {
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;
static final int OP_SET_PRIMARY_NAV = 8;
static final int OP_UNSET_PRIMARY_NAV = 9;
static final int OP_SET_MAX_LIFECYCLE = 10;
.
.
ArrayList<Op> mOps = new ArrayList<>();
}
2.2 Op類
- Op這個(gè)類對(duì)于后面add,hide,remove等操作很重要。
static final class Op {
int mCmd;
Fragment mFragment;
int mEnterAnim;
int mExitAnim;
int mPopEnterAnim;
int mPopExitAnim;
Lifecycle.State mOldMaxState;
Lifecycle.State mCurrentMaxState;
Op() {
}
.
.
}
2.3 BackStackRecord類
- 這個(gè)類就是真正執(zhí)行提交事務(wù)的類涝滴,提交事務(wù)會(huì)把自己一起傳給FragmentManager绣版。
- 還實(shí)現(xiàn)了 FragmentManager.OpGenerator 接口。
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, FragmentManager.OpGenerator {
final FragmentManager mManager;
@Override
public int commit() {
return commitInternal(false);
}
@Override
public int commitAllowingStateLoss() {
return commitInternal(true);
}
@Override
public void commitNow() {
disallowAddToBackStack();
mManager.execSingleAction(this, false);
}
@Override
public void commitNowAllowingStateLoss() {
disallowAddToBackStack();
mManager.execSingleAction(this, true);
}
}
3.add,hide,replace,remove
3.1 封裝歼疮,addOp
- 這里就分析一個(gè)replace,其他也是差不多的杂抽。
- 這里做的就是把要替換的控件id,fragment韩脏,tag缩麸,操作對(duì)應(yīng)的常量封裝進(jìn)Op類里。
/*FragmentTransaction*/
/**
* Calls {@link #replace(int, Fragment, String)} with a null tag.
*/
@NonNull
public FragmentTransaction replace(@IdRes int containerViewId, @NonNull Fragment fragment) {
return replace(containerViewId, fragment, null);
}
@NonNull
public FragmentTransaction replace(@IdRes int containerViewId, @NonNull Fragment fragment,
@Nullable String tag) {
//判斷數(shù)據(jù)有效性
if (containerViewId == 0) {
throw new IllegalArgumentException("Must use non-zero containerViewId");
}
doAddOp(containerViewId, fragment, tag, OP_REPLACE);
return this;
}
void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
.
.
//封裝進(jìn)Op
addOp(new Op(opcmd, fragment));
}
/**
* mOps 數(shù)組保持著這些操作
* 把fragment進(jìn)入退出動(dòng)畫一起加上赡矢,
* 可以去setCustomAnimations方法看
*/
void addOp(Op op) {
mOps.add(op);
op.mEnterAnim = mEnterAnim;
op.mExitAnim = mExitAnim;
op.mPopEnterAnim = mPopEnterAnim;
op.mPopExitAnim = mPopExitAnim;
}
4.commit
4.1 四種提交方式
- 提交事務(wù)有四種杭朱,分別是阅仔,先不分析四種區(qū)別,不是本次重點(diǎn)弧械。
1. commit()
2. commitAllowingStateLoss()
3. commitNow()
4. commitNowAllowingStateLoss()
4.2 提交事務(wù)
- commit 只能操作一次八酒,一次就把a(bǔ)dd,hide刃唐,replace等操作一起提交羞迷。
- 提交事務(wù)其實(shí)就是把自己一起丟給FragmentManager執(zhí)行。
@Override
public int commit() {
return commitInternal(false);
}
int commitInternal(boolean allowStateLoss) {
//只能commit一次画饥,否則拋異常
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) {
// 放入回退棧標(biāo)記的index
mIndex = mManager.allocBackStackIndex();
} else {
mIndex = -1;
}
//操作入隊(duì)
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
4.3 handler 發(fā)送
- commit 是在主線程異步執(zhí)行衔瓮,就是通過handler執(zhí)行。
/*FragmentManager*/
//保存操作
private final ArrayList<OpGenerator> mPendingActions = new ArrayList<>();
void enqueueAction(@NonNull OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
if (mHost == null) {
if (mDestroyed) {
//FragmentManager 已經(jīng) 銷毀
throw new IllegalStateException("FragmentManager has been destroyed");
} else {
//FragmentManager 還沒綁定
throw new IllegalStateException("FragmentManager has not been attached to a "
+ "host.");
}
}
checkStateLoss();
}
//加鎖
synchronized (mPendingActions) {
if (mHost == null) {
//commitAllowingStateLoss會(huì)走這里
if (allowStateLoss) {
// This FragmentManager isn't attached, so drop the entire transaction.
return;
}
throw new IllegalStateException("Activity has been destroyed");
}
//加入到數(shù)組
mPendingActions.add(action);
//最終來到這里
scheduleCommit();
}
}
- 到這終于看到handler了,用post(Runnable)發(fā)送出去荒澡。
void scheduleCommit() {
synchronized (mPendingActions) {
boolean postponeReady =
mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
boolean pendingReady = mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
//handler處理
mHost.getHandler().removeCallbacks(mExecCommit);
mHost.getHandler().post(mExecCommit);
updateOnBackPressedCallbackEnabled();
}
}
}
4.4 執(zhí)行execPendingActions
private Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions(true);
}
};
/**
* Only call from main thread!
*/
boolean execPendingActions(boolean allowStateLoss) {
ensureExecReady(allowStateLoss);
boolean didSomething = false;
//把事務(wù)放入臨時(shí)變量
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
try {
//優(yōu)化整理事務(wù)
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
}
didSomething = true;
}
...
return didSomething;
}
4.5 整理事務(wù)
- removeRedundantOperationsAndExecute 有一大段注釋报辱,注釋的意思就是說這方法刪除冗余的操作,合并重復(fù)的操作单山,就是優(yōu)化整理
- 重點(diǎn)看到 record.expandOps 方法碍现。
- 拿出 Op 里面記錄的操作,對(duì)不同操作處理米奸,added增加或者移除昼接,替換就是先移除再添加,具體可以看源碼悴晰,這里就不貼全部了慢睡,有點(diǎn)多。
/*FragmentManager*/
/**
* Remove redundant BackStackRecord operations and executes them. This method merges operations
* of proximate records that allow reordering. See
...
*/
private void removeRedundantOperationsAndExecute(@NonNull ArrayList<BackStackRecord> records,
@NonNull ArrayList<Boolean> isRecordPop) {
...
executeOpsTogether(records, isRecordPop, startIndex, recordNum);
...
private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records,
@NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
//展開整理
oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
...
}
//展開整理
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: {
...
}
break;
case OP_SET_PRIMARY_NAV: {
...
}
break;
}
}
return oldPrimaryNav;
}
4.6 執(zhí)行事務(wù)
- 這里的FragmentManager.executeOps方法铡溪,再進(jìn)入 BackStackRecord.executeOps方法漂辐,根據(jù)Op信息,處理再回到FragmentManager.moveToState方法棕硫。
/*FragmentManager*/
private void executeOpsTogether(@NonNull ArrayList<BackStackRecord> records,
@NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
...
executeOps(records, isRecordPop, startIndex, endIndex);
...
}
private static void executeOps(@NonNull ArrayList<BackStackRecord> records,
@NonNull ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
..
record.executeOps();
/*BackStackRecord*/
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;
...
switch (op.mCmd) {
case OP_ADD:
f.setAnimations(op.mEnterAnim, op.mExitAnim, op.mPopEnterAnim, op.mPopExitAnim);
mManager.setExitAnimationOrder(f, false);
mManager.addFragment(f);
break;
.
.
.
}
}
if (!mReorderingAllowed && !FragmentManager.USE_STATE_MANAGER) {
// Added fragments are added at the end to comply with prior behavior.
mManager.moveToState(mManager.mCurState, true);
}
}
4.7 狀態(tài)改變
- 首先我們能看到Fragment 的狀態(tài)常量有哪些髓涯,其實(shí)有的版本,比如1.2.0只有5個(gè)哈扮,那這幾個(gè)怎么夠呢纬纪,好像生命周期不止這幾個(gè)啊,就是創(chuàng)建時(shí)正著來滑肉,銷毀時(shí)再反著來就行了包各。
public class Fragment implements ... {
static final Object USE_DEFAULT_TRANSITION = new Object();
static final int INITIALIZING = -1; // Not yet attached.
static final int ATTACHED = 0; // Attached to the host.
static final int CREATED = 1; // Created.
static final int VIEW_CREATED = 2; // View Created.
static final int AWAITING_EXIT_EFFECTS = 3; // Downward state, awaiting exit effects
static final int ACTIVITY_CREATED = 4; // Fully created, not started.
static final int STARTED = 5; // Created and started, not resumed.
static final int AWAITING_ENTER_EFFECTS = 6; // Upward state, awaiting enter effects
static final int RESUMED = 7; // Created started and resumed.
int mState = INITIALIZING;
}
- moveToState的代碼是本次關(guān)鍵。
- newState = Math.min(newState, fragmentStateManager.computeExpectedState())靶庙,這里跟官方提供的懶加載有關(guān)问畅,可以限制fragment執(zhí)行到哪個(gè)階段,但現(xiàn)在先不管他。
- if (f.mState <= newState) 按声,如果true , 可以看到后面的代碼是創(chuàng)建流程膳犹,比如 Fragment.INITIALIZING ,ATTACHED签则,CREATED等等须床,否則就是銷毀流程,這里就放一部分代碼渐裂,可以自己去源碼看看所有流程豺旬。
void moveToState(int newState, boolean always) {
...
moveFragmentToExpectedState(f);
...
}
void moveFragmentToExpectedState(@NonNull Fragment f) {
...
moveToState(f);
...
}
void moveToState(@NonNull Fragment f) {
moveToState(f, mCurState);
}
void moveToState(@NonNull Fragment f, int newState) {
//獲取FragmentStateManager
FragmentStateManager fragmentStateManager = mFragmentStore.getFragmentStateManager(f.mWho);
if (fragmentStateManager == null) {
fragmentStateManager = new FragmentStateManager(mLifecycleCallbacksDispatcher,
mFragmentStore, f);
fragmentStateManager.setFragmentManagerState(Fragment.CREATED);
}
if (f.mFromLayout && f.mInLayout && f.mState == Fragment.VIEW_CREATED) {
newState = Math.max(newState, Fragment.VIEW_CREATED);
}
//這里跟官方提供的懶加載有關(guān),可以限制fragment執(zhí)行到哪個(gè)階段
newState = Math.min(newState, fragmentStateManager.computeExpectedState());
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) {
fragmentStateManager.attach();
}
// 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();
}
// fall through
...
}
} else if (f.mState > newState) {
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
fragmentStateManager.pause();
}
// fall through
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
fragmentStateManager.stop();
}
// fall through
...
}
}
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;
}
}
4.8 終于到fragment的生命周期執(zhí)行
- 這里有一個(gè)FragmentStateManager柒凉,就是他才是真正的調(diào)用Fragment 的生命周期方法族阅,我們終于看到熟悉的身影,F(xiàn)ragment 的 onCreateView方法膝捞。
- 這里看onCreateView 坦刀,我們最常用的方法,其他也是一樣樣的蔬咬,大家也可以嘗試自己去分析鲤遥。
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
fragmentStateManager.createView();
}
/*FragmentStateManager*/
void createView() {
...
mFragment.performCreateView(layoutInflater, container, mFragment.mSavedFragmentState);
...
}
/*Fragment*/
void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
mChildFragmentManager.noteStateNotSaved();
mPerformedCreateView = true;
mViewLifecycleOwner = new FragmentViewLifecycleOwner(getViewModelStore());
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
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;
}
}
5.流程圖
-
搭配流程圖看可能會(huì)好一些。
流程圖 - 如果有錯(cuò)幫忙指出林艘,謝謝盖奈。