- 本次分析Fragment 1.3.4版本,不同版本源码会不同!
- 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 无论是单独使用还是配合Viewpager,对于Android开发来说非常熟悉了,但生命周期,一般就网上看到的一张图,想必大家也经常看到;
- 那Fragment的生命周期在什么时候调用的,commit之后怎么走到生命周期的每一个方法,需要看源码才知道,本文就此分析。
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数组哦,他是 FragmentController ,这个很重要,先记住他。
/* FragmentActivity类 */
//创建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() 传进去,再获取 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 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 {
}
- 到此就获取一个fragmentManager。
2.beginTransaction
- 每次处理Fragment的事务都是新建一个 BackStackRecord 回退栈 ,只能用一次。
@NonNull
public FragmentTransaction beginTransaction() {
return new BackStackRecord(this);
}
2.1 FragmentTransaction类
- BackStackRecord 类是继承 抽象类FragmentTransaction,这里有非常重要的各个OP常量,还有内部类OP。
- add,hide,remove等操作也是在这个类,他们都会封装进Op,用数组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 mOps = new ArrayList<>();
}
2.2 Op类
- Op这个类对于后面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类
- 这个类就是真正执行提交事务的类,提交事务会把自己一起传给FragmentManager。
- 还实现了 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
- 这里就分析一个replace,其他也是差不多的。
- 这里做的就是把要替换的控件id,fragment,tag,操作对应的常量封装进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) {
//判断数据有效性
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) {
.
.
//封装进Op
addOp(new Op(opcmd, fragment));
}
/**
* mOps 数组保持着这些操作
* 把fragment进入退出动画一起加上,
* 可以去setCustomAnimations方法看
*/
void addOp(Op op) {
mOps.add(op);
op.mEnterAnim = mEnterAnim;
op.mExitAnim = mExitAnim;
op.mPopEnterAnim = mPopEnterAnim;
op.mPopExitAnim = mPopExitAnim;
}
4.commit
4.1 四种提交方式
- 提交事务有四种,分别是,先不分析四种区别,不是本次重点。
1. commit()
2. commitAllowingStateLoss()
3. commitNow()
4. commitNowAllowingStateLoss()
4.2 提交事务
- commit 只能操作一次,一次就把add,hide,replace等操作一起提交。
- 提交事务其实就是把自己一起丢给FragmentManager执行。
@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) {
// 放入回退栈标记的index
mIndex = mManager.allocBackStackIndex();
} else {
mIndex = -1;
}
//操作入队
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
4.3 handler 发送
- commit 是在主线程异步执行,就是通过handler执行。
/*FragmentManager*/
//保存操作
private final ArrayList mPendingActions = new ArrayList<>();
void enqueueAction(@NonNull OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
if (mHost == null) {
if (mDestroyed) {
//FragmentManager 已经 销毁
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会走这里
if (allowStateLoss) {
// This FragmentManager isn't attached, so drop the entire transaction.
return;
}
throw new IllegalStateException("Activity has been destroyed");
}
//加入到数组
mPendingActions.add(action);
//最终来到这里
scheduleCommit();
}
}
- 到这终于看到handler了,用post(Runnable)发送出去。
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 执行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;
//把事务放入临时变量
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
try {
//优化整理事务
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
}
didSomething = true;
}
...
return didSomething;
}
4.5 整理事务
- removeRedundantOperationsAndExecute 有一大段注释,注释的意思就是说这方法删除冗余的操作,合并重复的操作,就是优化整理
- 重点看到 record.expandOps 方法。
- 拿出 Op 里面记录的操作,对不同操作处理,added增加或者移除,替换就是先移除再添加,具体可以看源码,这里就不贴全部了,有点多。
/*FragmentManager*/
/**
* Remove redundant BackStackRecord operations and executes them. This method merges operations
* of proximate records that allow reordering. See
...
*/
private void removeRedundantOperationsAndExecute(@NonNull ArrayList records,
@NonNull ArrayList isRecordPop) {
...
executeOpsTogether(records, isRecordPop, startIndex, recordNum);
...
private void executeOpsTogether(@NonNull ArrayList records,
@NonNull ArrayList isRecordPop, int startIndex, int endIndex) {
//展开整理
oldPrimaryNav = record.expandOps(mTmpAddedFragments, oldPrimaryNav);
...
}
//展开整理
Fragment expandOps(ArrayList 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 执行事务
- 这里的FragmentManager.executeOps方法,再进入 BackStackRecord.executeOps方法,根据Op信息,处理再回到FragmentManager.moveToState方法。
/*FragmentManager*/
private void executeOpsTogether(@NonNull ArrayList records,
@NonNull ArrayList isRecordPop, int startIndex, int endIndex) {
...
executeOps(records, isRecordPop, startIndex, endIndex);
...
}
private static void executeOps(@NonNull ArrayList records,
@NonNull ArrayList 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 状态改变
- 首先我们能看到Fragment 的状态常量有哪些,其实有的版本,比如1.2.0只有5个,那这几个怎么够呢,好像生命周期不止这几个啊,就是创建时正着来,销毁时再反着来就行了。
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的代码是本次关键。
- newState = Math.min(newState, fragmentStateManager.computeExpectedState()),这里跟官方提供的懒加载有关,可以限制fragment执行到哪个阶段,但现在先不管他。
- if (f.mState <= newState) ,如果true , 可以看到后面的代码是创建流程,比如 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);
}
//这里跟官方提供的懒加载有关,可以限制fragment执行到哪个阶段
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的生命周期执行
- 这里有一个FragmentStateManager,就是他才是真正的调用Fragment 的生命周期方法,我们终于看到熟悉的身影,Fragment 的 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.流程图
-
搭配流程图看可能会好一些。
- 如果有错帮忙指出,谢谢。