基于AndroidX源码分析
Activity与Fragment 之间的关系
- Fragment是Activity界面的一部分,Fragment是依附于Activity之上的;
- Activity是Fragment的基础,Fragment是Activity的延续和发展
- 一个Activity可以有多个Fragment,一个Fragment也可以被多个Activity重复使用;
- 一个Fragment除了Activity处于onResume状态下,他可以自己灵活的控制自己的生命周期,其他状态下,其生命周期都是由Activity所决定的;
- Fragment的出现增强了UI界面布局的灵活性,可以实现动态的改变UI布局;
Fragment生命周期
这是一张google官方提供的一张Fragment生命周期的图片,Fragment的生命周期又依赖与Activity
我们通过上面图开始进入我们的源码的分析
一、FragmentController 创建
在FragmentActivity中有个变量mFragments,在一开始就初始化完成
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
整个类图结构图如上所示,里面的细节会在后续流程会讲到。
二、生命周期分发
我们Fragment的生命周期会跟随Activity的生命周期进行变化,所以我们看几个生命周期的调用。
protected void onCreate(@Nullable Bundle savedInstanceState) {
//调用attach
mFragments.attachHost(null /*parent*/);
if (savedInstanceState != null) {
//... 数据保存相关
}
//...
super.onCreate(savedInstanceState);
//分发create
mFragments.dispatchCreate();
}
protected void onPostResume() {
super.onPostResume();
//分发Resume,会在onResume之前执行
mFragments.dispatchResume();
}
protected void onPause() {
super.onPause();
mResumed = false;
//分发Pause
mFragments.dispatchPause();
}
上面的代码可以看到随着Activity生命周期的变化会调用FragmentManagerImpl.dispatchXXX()
通知。跟踪代码我们会发现FragmentManagerImpl.dispatchXXX()
最终都会调用FragmentManagerImpl.dispatchStateChange(int nextState)
Fragment状态
Fragment有多个状态值来标示当前自己生命周期所处的状态
static final int INITIALIZING = 0; // Not yet created.
static final int CREATED = 1; // Created.
static final int ACTIVITY_CREATED = 2; // Fully created, not started.
static final int STARTED = 3; // Created and started, not resumed.
static final int RESUMED = 4; // Created started and resumed.
//Fragment 默认的状态是 INITIALIZING,也是代表当前的生命周期状态
int mState = INITIALIZING;
FragmentManagerImpl.dispatchStateChange
//nextState 顾名思义,就是想要Fragment进入的下一个状态
private void dispatchStateChange(int nextState) {
try {
//这个标志位是为了防止
mExecutingActions = true;
//1.变化到下一个状态
moveToState(nextState, false);
} finally {
mExecutingActions = false;
}
//执行未执行的操作事务管理会讲到
execPendingActions();
}
三、生命周期变化 moveToState
第1步
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
final int numAdded = mAdded.size();
for (int i = 0; i < numAdded; i++) {
Fragment f = mAdded.get(i);
//【1-1】所有的Fragment都会调用这个方法,但不会真的更新状态看【2-1】
moveFragmentToExpectedState(f);
}
// Now iterate through all active fragments. These will include those that are removed
// and detached.
//一些特殊的情况,比如被回收了 remove 和 detached 不会再mAdded列表里面
for (Fragment f : mActive.values()) {
if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
//【1-2】被回收的再执行生命周期变化
moveFragmentToExpectedState(f);
}
}
//比如有些Fragment 需要等到其他Fragment执行完毕之后在执行自己的生命周期变化,比如说用户不可见的,需要让用户可见的先执行生命周期,再轮到自己。这也是google优化的思路,那么什么时候延迟 todo
//【1-3】开始执行延迟的Fragment 生命周期变化【3-1】
startPendingDeferredFragments();
//。。。
}
【1-3】 startPendingDeferredFragments
=> performPendingDeferredStart
public void performPendingDeferredStart(Fragment f) {
if (f.mDeferStart) {
if (mExecutingActions) {
mHavePendingDeferredStart = true;
return;
}
//把延迟加载标记清空
f.mDeferStart = false;
//接着走后面的生命周期 到第三步
moveToState(f, mCurState, 0, 0, false);
}
}
第2步
void moveFragmentToExpectedState(Fragment f) {
if (f == null) {
return;
}
//【2-1】.mActive存在key 才能继续执行
if (!mActive.containsKey(f.mWho)) {
return;
}
int nextState = mCurState;
if (f.mRemoving) {
//如果被移出 控制他的生命周期nextState不能超过预期
if (f.isInBackStack()) {
nextState = Math.min(nextState, Fragment.CREATED);
} else {
nextState = Math.min(nextState, Fragment.INITIALIZING);
}
}
//【2-2】进入真正的状态
moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
//...
}
第3步
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
//未添加或detached了先走oncreate
if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
newState = Fragment.CREATED;
}
//在此控制newState 如果被移出 控制他的生命周期nextState不能超过预期
if (f.mRemoving && newState > f.mState) {
if (f.mState == Fragment.INITIALIZING && f.isInBackStack()) {
// Allow the fragment to be created so that it can be saved later.
newState = Fragment.CREATED;
} else {
// While removing a fragment, we can't change it to a higher state.
newState = f.mState;
}
}
//延迟加载则将newState 直接赋值为 Fragment.ACTIVITY_CREATED , 他将不会执行 CREATED 和 INITIALIZING,而直接跳过本次的生命周期
if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.ACTIVITY_CREATED) {
newState = Fragment.ACTIVITY_CREATED;
}
//控制Fragment 最大生命周期执行到哪一步,在ViewPager2 用的比较多
if (f.mMaxState == Lifecycle.State.CREATED) {
newState = Math.min(newState, Fragment.CREATED);
} else {
newState = Math.min(newState, f.mMaxState.ordinal());
}
if (f.mState <= newState) {
//...
//switch 当前状态
switch (f.mState) {
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {//执行这里面说明要走到CREATE生命周期状态
if (f.mSavedFragmentState != null) {
//...状态恢复
//【3-1】如果Fragment用户不可见不让他走到START,等所有执行完再走【1-3】
if (!f.mUserVisibleHint) {
f.mDeferStart = true;
if (newState > Fragment.ACTIVITY_CREATED) {
newState = Fragment.ACTIVITY_CREATED;
}
}
}
f.mHost = mHost;
f.mParentFragment = mParent;
f.mFragmentManager = mParent != null
? mParent.mChildFragmentManager : mHost.mFragmentManager;
//优先执行Childfragment依赖的ParentFragment
if (f.mTarget != null) {
if (f.mTarget.mState < Fragment.CREATED) {
moveToState(f.mTarget, Fragment.CREATED, 0, 0, true);
}
f.mTargetWho = f.mTarget.mWho;
f.mTarget = null;
}
if (f.mTargetWho != null) {
Fragment target = mActive.get(f.mTargetWho);
if (target.mState < Fragment.CREATED) {
moveToState(target, Fragment.CREATED, 0, 0, true);
}
}
//生命周期的回调和分发
dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
//fragment attach
f.performAttach();
if (f.mParentFragment == null) {
mHost.onAttachFragment(f);
} else {
f.mParentFragment.onAttachFragment(f);
}
dispatchOnFragmentAttached(f, mHost.getContext(), false);
//f.mState 标记为 CREATED
if (!f.mIsCreated) {
dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
f.performCreate(f.mSavedFragmentState);
dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = Fragment.CREATED;
}
}
case Fragment.CREATED:
if (newState > Fragment.INITIALIZING) {
//创建FragmentView
ensureInflatedFragmentView(f);
}
if (newState > Fragment.CREATED) {//执行这里面说明要走到ACTIVITY_CREATE生命周期状态
if (!f.mFromLayout) {
//...把Fragment的 View 添加到 Activity View容器
}
//f.mState 标记为 ACTIVITY_CREATED
f.performActivityCreated(f.mSavedFragmentState);
dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {//执行这里面说明要走到START生命周期状态
f.performStart();
dispatchOnFragmentStarted(f, false);
}
case Fragment.STARTED:
if (newState > Fragment.STARTED) {//执行这里面说明要走到RESUME生命周期状态
//执行Fragment Resume
f.performResume();
//分发生命周期监听的回调
dispatchOnFragmentResumed(f, false);
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}
} else if (f.mState > newState) {
// 省略反向从 RESUME =》 INITIALIZING 大家可以自己分析,比正向的简单
}
//设置fragment 当前state
if (f.mState != newState) {
f.mState = newState;
}
}
事务管理
将一个Fragment添加到Activity布局有两种方式。
- 通过fragment标签加入(静态加入)
- 通过代码动态的加入(动态加入)
而这里要讲的就是第二种方式。
事务的action
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;
事务添加的流程
事务四种Commit的区别
在 Fragment 之间传递数据
为了重复使用 Fragment 界面组件,您应将每个组件构建为一个完全独立的模块化组件,定义它自己的布局和行为。定义这些可重用的 Fragment 后,您可以将它们与 Activity 相关联,并将其与应用逻辑相关联以实现整个复合界面。
在AndroidX Fragment版本是 1.3.0-alpha04
开始,每个 FragmentManager
都会实现 FragmentResultOwner
。我们实现Fragment之间的通信。
- 两个同级Fragment之间数据传递,双向传递
- 子Fragment向父Fragment数据传递,ChildFragment => ParentFragment
- 通过Jetpack 的 ViewModel和LiveData 组件进行通信,通过共享ViewModel,使用LiveData 就可以进行数据的双向通信了。后面讲解MVVM架构原理的时候会带上这里遗留的通信方式。
我们可以看到 上面通信条件必须是在同一个Activity下面,如果跨越Acitivty的话那就是生命周期大于Acitivity 全局的观察着设计模式了,有RxJava, EventBus、LiveDataBus 这些比较成熟的线程间的通信开源组件了。
状态保存和恢复
状态保存
当Activity在后台被回收或者App的进程处于Sleep状态等特殊情况时候会调用ActivityThread.callActivityOnSaveInstanceState
=> Instrumentation.callActivityOnSaveInstanceState
=> Activity.performSaveInstanceState
=> Activity.onSaveInstanceState
=> FragmentActivity.onSaveInstanceState
来保存数据
FragmentActivity.onSaveInstanceState
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
//将Fragment的状态变更为CREATE
markFragmentsCreated();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
//1.封装所有fragment需要保存的状态数据
Parcelable p = mFragments.saveAllState();
if (p != null) {
//2.把数据保存到bundle中
outState.putParcelable(FRAGMENTS_TAG, p);
}
if (mPendingFragmentActivityResults.size() > 0) {
outState.putInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG, mNextCandidateRequestIndex);
int[] requestCodes = new int[mPendingFragmentActivityResults.size()];
String[] fragmentWhos = new String[mPendingFragmentActivityResults.size()];
for (int i = 0; i < mPendingFragmentActivityResults.size(); i++) {
requestCodes[i] = mPendingFragmentActivityResults.keyAt(i);
fragmentWhos[i] = mPendingFragmentActivityResults.valueAt(i);
}
outState.putIntArray(ALLOCATED_REQUEST_INDICIES_TAG, requestCodes);
outState.putStringArray(REQUEST_FRAGMENT_WHO_TAG, fragmentWhos);
}
}
第一步方法执行之后mFragments.saveAllState
=> FragmentController.saveAllState
=> FragmentManagerImpl.saveAllState
最总进入FragmentManagerImpl.saveAllState
FragmentManagerImpl.saveAllState
Parcelable saveAllState() {
//确保所有等待操作的都已处理完,再进入保存数据
forcePostponedTransactions();
endAnimatingAwayFragments();
execPendingActions();
//1.标志位置为true,在mStateSaved == true 的时候commit会抛出异常
mStateSaved = true;
//fragment 为空,也就是没有Fragment 添加到 FragmentManager
if (mActive.isEmpty()) {
return null;
}
// First collect all active fragments.
int size = mActive.size();
ArrayList<FragmentState> active = new ArrayList<>(size);
boolean haveFragments = false;
//遍历所有活跃的fragment
for (Fragment f : mActive.values()) {
if (f != null) {
if (f.mFragmentManager != this) {
throwException(new IllegalStateException(
"Failure saving state: active " + f
+ " was removed from the FragmentManager"));
}
haveFragments = true;
//2.用于保存fragment的成员变量,并添加到 active,用于数据恢复
FragmentState fs = new FragmentState(f);
active.add(fs);
if (f.mState > Fragment.INITIALIZING && fs.mSavedFragmentState == null) {
//保存基本状态
fs.mSavedFragmentState = saveFragmentBasicState(f);
if (f.mTargetWho != null) {
Fragment target = mActive.get(f.mTargetWho);
if (fs.mSavedFragmentState == null) {
fs.mSavedFragmentState = new Bundle();
}
putFragment(fs.mSavedFragmentState,
FragmentManagerImpl.TARGET_STATE_TAG, target);
if (f.mTargetRequestCode != 0) {
fs.mSavedFragmentState.putInt(
FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG,
f.mTargetRequestCode);
}
}
} else {
fs.mSavedFragmentState = f.mSavedFragmentState;
}
}
}
if (!haveFragments) {
return null;
}
ArrayList<String> added = null;
BackStackState[] backStack = null;
// Build list of currently added fragments.
size = mAdded.size();
if (size > 0) {
//遍历所有添加到FragmentManager的Fragment
added = new ArrayList<>(size);
for (Fragment f : mAdded) {
//f.mWho fragment 唯一标识
added.add(f.mWho);
}
}
//保存回退栈
// Now save back stack.
if (mBackStack != null) {
size = mBackStack.size();
if (size > 0) {
backStack = new BackStackState[size];
for (int i = 0; i < size; i++) {
backStack[i] = new BackStackState(mBackStack.get(i));
}
}
}
//3。保存FragmentManagerImpl的整体信息
FragmentManagerState fms = new FragmentManagerState();
fms.mActive = active;
fms.mAdded = added;
fms.mBackStack = backStack;
if (mPrimaryNav != null) {
fms.mPrimaryNavActiveWho = mPrimaryNav.mWho;
}
fms.mNextFragmentIndex = mNextFragmentIndex;
return fms;
}
通过上面几个步骤最终将我们的数据保存到ActivityClienttRecord的成员变量 state 中
状态恢复
当Activity恢复的时候会创建一个新的Activity,并走一遍Activity的生命周期方法。
FragmentActivity.onCreate
- =>
FragmentController.restoreSaveState
=>FragmentManagerImpl.restoreSaveState
恢复数据 - =>
FragmentController.dispatchCreate
=>FragmentManagerImpl.dispatchCreate
重走Fragment的生命周期
FragmentManagerImpl.restoreSaveState
void restoreSaveState(Parcelable state) {
// If there is no saved state at all, then there's nothing else to do
if (state == null) return;
FragmentManagerState fms = (FragmentManagerState)state;
if (fms.mActive == null) return;
// First re-attach any non-config instances we are retaining back
// to their saved state, so we don't try to instantiate them again.
for (Fragment f : mNonConfig.getRetainedFragments()) {
FragmentState fs = null;
for (FragmentState fragmentState : fms.mActive) {
if (fragmentState.mWho.equals(f.mWho)) {
fs = fragmentState;
break;
}
}
if (fs == null) {
// We need to ensure that onDestroy and any other clean up is done
// so move the Fragment up to CREATED, then mark it as being removed, then
// destroy it.
moveToState(f, Fragment.CREATED, 0, 0, false);
f.mRemoving = true;
moveToState(f, Fragment.INITIALIZING, 0, 0, false);
continue;
}
fs.mInstance = f;
f.mSavedViewState = null;
f.mBackStackNesting = 0;
f.mInLayout = false;
f.mAdded = false;
f.mTargetWho = f.mTarget != null ? f.mTarget.mWho : null;
f.mTarget = null;
if (fs.mSavedFragmentState != null) {
fs.mSavedFragmentState.setClassLoader(mHost.getContext().getClassLoader());
f.mSavedViewState = fs.mSavedFragmentState.getSparseParcelableArray(
FragmentManagerImpl.VIEW_STATE_TAG);
f.mSavedFragmentState = fs.mSavedFragmentState;
}
}
//先清空活跃的Fragment
mActive.clear();
//从缓存中取出FragmentState 恢复活跃的Fragment并添加到mActive中
for (FragmentState fs : fms.mActive) {
if (fs != null) {
Fragment f = fs.instantiate(mHost.getContext().getClassLoader(),
getFragmentFactory());
f.mFragmentManager = this;
if (DEBUG) Log.v(TAG, "restoreSaveState: active (" + f.mWho + "): " + f);
mActive.put(f.mWho, f);
fs.mInstance = null;
}
}
// Build the list of currently added fragments.
//同理恢复add的Fragment
mAdded.clear();
if (fms.mAdded != null) {
for (String who : fms.mAdded) {
Fragment f = mActive.get(who);
if (f == null) {
throwException(new IllegalStateException(
"No instantiated fragment for (" + who + ")"));
}
f.mAdded = true;
if (mAdded.contains(f)) {
throw new IllegalStateException("Already added " + f);
}
synchronized (mAdded) {
mAdded.add(f);
}
}
}
// Build the back stack.
if (fms.mBackStack != null) {
mBackStack = new ArrayList<BackStackRecord>(fms.mBackStack.length);
for (int i=0; i<fms.mBackStack.length; i++) {
BackStackRecord bse = fms.mBackStack[i].instantiate(this);
mBackStack.add(bse);
if (bse.mIndex >= 0) {
setBackStackIndex(bse.mIndex, bse);
}
}
} else {
mBackStack = null;
}
if (fms.mPrimaryNavActiveWho != null) {
mPrimaryNav = mActive.get(fms.mPrimaryNavActiveWho);
dispatchParentPrimaryNavigationFragmentChanged(mPrimaryNav);
}
this.mNextFragmentIndex = fms.mNextFragmentIndex;
}