Android知识总结
注意:分析的是 androidx
一、生命周期调用流程
运用Fragment
时,Activity 要继承 FragmentActivity
,我们先看FragmentActivity#onCreate
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
protected void onCreate(@Nullable Bundle savedInstanceState) {
mFragments.attachHost(null /*parent*/);
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
//把之前保存的数据取回来
mFragments.restoreSaveState(p);
// Check if there are any pending onActivityResult calls to descendent Fragments.
if (savedInstanceState.containsKey(NEXT_CANDIDATE_REQUEST_INDEX_TAG)) {
mNextCandidateRequestIndex =
savedInstanceState.getInt(NEXT_CANDIDATE_REQUEST_INDEX_TAG);
int[] requestCodes = savedInstanceState.getIntArray(ALLOCATED_REQUEST_INDICIES_TAG);
String[] fragmentWhos = savedInstanceState.getStringArray(REQUEST_FRAGMENT_WHO_TAG);
if (requestCodes == null || fragmentWhos == null ||
requestCodes.length != fragmentWhos.length) {
Log.w(TAG, "Invalid requestCode mapping in savedInstanceState.");
} else {
mPendingFragmentActivityResults = new SparseArrayCompat<>(requestCodes.length);
for (int i = 0; i < requestCodes.length; i++) {
mPendingFragmentActivityResults.put(requestCodes[i], fragmentWhos[i]);
}
}
}
}
if (mPendingFragmentActivityResults == null) {
mPendingFragmentActivityResults = new SparseArrayCompat<>();
mNextCandidateRequestIndex = 0;
}
super.onCreate(savedInstanceState);
//更改状态
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_CREATE);
//分发 炽热create 事件
mFragments.dispatchCreate();
}
接下来看FragmentController#dispatchCreate
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
调用FragmentManagerImpl#dispatchCreate
public void dispatchCreate() {
//保存状态的标志位 = false
mStateSaved = false;
mStopped = false;
dispatchStateChange(Fragment.CREATED);
}
private void dispatchStateChange(int nextState) {
try {
mExecutingActions = true;
//重新执行fragment生命周期
moveToState(nextState, false);
} finally {
mExecutingActions = false;
}
execPendingActions();
}
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);
//最终会执行 moveToState 重新执行fragment生命周期
//把 mAdded 集合的 fragment 移动到期望的状态
moveFragmentToExpectedState(f);
}
// Now iterate through all active fragments. These will include those that are removed
// and detached.
for (Fragment f : mActive.values()) {
if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
//最终会执行 moveToState 重新执行fragment生命周期
moveFragmentToExpectedState(f);
}
}
startPendingDeferredFragments();
if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
mHost.onSupportInvalidateOptionsMenu();
mNeedMenuInvalidate = false;
}
}
接下来我们看FragmentActivity#onCreateView
方法创建view,的过程
public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
// 创建 Fragment 的视图
final View v = dispatchFragmentsOnCreateView(parent, name, context, attrs);
if (v == null) {
//执行父类的 onCreateView
return super.onCreateView(parent, name, context, attrs);
}
return v;
}
@Nullable
final View dispatchFragmentsOnCreateView(@Nullable View parent, @NonNull String name,
@NonNull Context context, @NonNull AttributeSet attrs) {
//执行 FragmentController 的 onCreateView
return mFragments.onCreateView(parent, name, context, attrs);
}
FragmentController
时 Fragment 的控制器, FragmentActivity
上的所有生命周期相关API都会调用FragmentController
对应的dispatchXXX()
。
//FragmentManagerImpl 是 FragmentManager 的实现类
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
return mHost.mFragmentManager.onCreateView(parent, name, context, attrs);
}
执行FragmentManagerImpl#onCreateView
方法
public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context,
@NonNull AttributeSet attrs) {
if (!"fragment".equals(name)) {
return null;
}
String fname = attrs.getAttributeValue(null, "class");
TypedArray a = context.obtainStyledAttributes(attrs, FragmentManagerImpl.FragmentTag.Fragment);
if (fname == null) {
fname = a.getString(FragmentManagerImpl.FragmentTag.Fragment_name);
}
int id = a.getResourceId(FragmentManagerImpl.FragmentTag.Fragment_id, View.NO_ID);
String tag = a.getString(FragmentManagerImpl.FragmentTag.Fragment_tag);
a.recycle();
if (fname == null || !FragmentFactory.isFragmentClass(context.getClassLoader(), fname)) {
return null;
}
int containerId = parent != null ? parent.getId() : 0;
if (containerId == View.NO_ID && id == View.NO_ID && tag == null) {
throw new IllegalArgumentException(attrs.getPositionDescription()
+ ": Must specify unique android:id, android:tag, or have a parent with an id for " + fname);
}
//如果 id != -1,通过 id 创建 fragment
Fragment fragment = id != View.NO_ID ? findFragmentById(id) : null;
if (fragment == null && tag != null) {
//通过 tag 创建 fragment
fragment = findFragmentByTag(tag);
}
if (fragment == null && containerId != View.NO_ID) {
//通过 id 创建 fragment
fragment = findFragmentById(containerId);
}
if (FragmentManagerImpl.DEBUG) Log.v(TAG, "onCreateView: id=0x"
+ Integer.toHexString(id) + " fname=" + fname
+ " existing=" + fragment);
if (fragment == null) {
//通过反射创建 Fragment
fragment = getFragmentFactory().instantiate(context.getClassLoader(), fname);
fragment.mFromLayout = true;
fragment.mFragmentId = id != 0 ? id : containerId;
fragment.mContainerId = containerId;
fragment.mTag = tag;
fragment.mInLayout = true;
fragment.mFragmentManager = this;
fragment.mHost = mHost;
fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState);
addFragment(fragment, true);
} else if (fragment.mInLayout) {
// A fragment already exists and it is not one we restored from
// previous state.
throw new IllegalArgumentException(attrs.getPositionDescription()
+ ": Duplicate id 0x" + Integer.toHexString(id)
+ ", tag " + tag + ", or parent id 0x" + Integer.toHexString(containerId)
+ " with another fragment for " + fname);
} else {
// This fragment was retained from a previous instance; get it
// going now.
fragment.mInLayout = true;
fragment.mHost = mHost;
// Give the Fragment the attributes to initialize itself.
fragment.onInflate(mHost.getContext(), attrs, fragment.mSavedFragmentState);
}
//当前的状态 mCurState < CREATED
if (mCurState < Fragment.CREATED && fragment.mFromLayout) {
//更新状态,执行 fragment 的生命周期
moveToState(fragment, Fragment.CREATED, 0, 0, false);
} else {
moveToState(fragment);
}
if (fragment.mView == null) {
throw new IllegalStateException("Fragment " + fname
+ " did not create a view.");
}
if (id != 0) {
//设置 id
fragment.mView.setId(id);
}
if (fragment.mView.getTag() == null) {
//设置 tag
fragment.mView.setTag(tag);
}
return fragment.mView;
}
执行FragmentManagerImpl#moveToState
void moveToState(Fragment f, int newState, int transit, int transitionStyle,
boolean keepActive) {
// 还没有添加的 Fragment 处于 onCreate() 状态
if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {
newState = Fragment.CREATED;
}
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;
}
}
// Defer start if requested; don't allow it to move to STARTED or higher
// if it's not already started.
//推迟启动的设置为 created
if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.ACTIVITY_CREATED) {
newState = Fragment.ACTIVITY_CREATED;
}
// Don't allow the Fragment to go above its max lifecycle state
// Ensure that Fragments are capped at CREATED instead of ACTIVITY_CREATED.
if (f.mMaxState == Lifecycle.State.CREATED) {
newState = Math.min(newState, Fragment.CREATED);
} else {
newState = Math.min(newState, f.mMaxState.ordinal());
}
if (f.mState <= newState) {
// fragment 里面的 mState 小于 当前的状态(newState),mState默认 INITIALIZING
if (f.mFromLayout && !f.mInLayout) {
return;
}
if (f.getAnimatingAway() != null || f.getAnimator() != null) {
f.setAnimatingAway(null);
f.setAnimator(null);
//如果当前 Fragment 正有动画,直接修改为最终状态
moveToState(f, f.getStateAfterAnimating(), 0, 0, true);
}
switch (f.mState) {
case Fragment.INITIALIZING:
if (newState > Fragment.INITIALIZING) {
if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);
if (f.mSavedFragmentState != null) {
f.mSavedFragmentState.setClassLoader(mHost.getContext()
.getClassLoader());
f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(
FragmentManagerImpl.VIEW_STATE_TAG);
Fragment target = getFragment(f.mSavedFragmentState,
FragmentManagerImpl.TARGET_STATE_TAG);
f.mTargetWho = target != null ? target.mWho : null;
if (f.mTargetWho != null) {
f.mTargetRequestCode = f.mSavedFragmentState.getInt(
FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);
}
if (f.mSavedUserVisibleHint != null) {
f.mUserVisibleHint = f.mSavedUserVisibleHint;
f.mSavedUserVisibleHint = null;
} else {
f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(
FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);
}
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;
// 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 (mActive.get(f.mTarget.mWho) != f.mTarget) {
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, 0, 0, true);
}
f.mTargetWho = f.mTarget.mWho;
f.mTarget = null;
}
if (f.mTargetWho != null) {
Fragment target = mActive.get(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, 0, 0, true);
}
}
dispatchOnFragmentPreAttached(f, mHost.getContext(), false);
//调用 Fragment 生命周期 onAttach 方法
f.performAttach();
if (f.mParentFragment == null) {
mHost.onAttachFragment(f);
} else {
f.mParentFragment.onAttachFragment(f);
}
dispatchOnFragmentAttached(f, mHost.getContext(), false);
if (!f.mIsCreated) {
dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
//调用 Fragment生命周期 onCreate 方法
f.performCreate(f.mSavedFragmentState);
dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = Fragment.CREATED;
}
}
// fall through
case Fragment.CREATED:
if (newState > Fragment.INITIALIZING) {
ensureInflatedFragmentView(f);
}
if (newState > Fragment.CREATED) {
if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
if (f.mContainerId == View.NO_ID) {
throwException(new IllegalArgumentException(
"Cannot create fragment "
+ f
+ " for a container view with no id"));
}
container = (ViewGroup) mContainer.onFindViewById(f.mContainerId);
if (container == null && !f.mRestored) {
String resName;
try {
resName = f.getResources().getResourceName(f.mContainerId);
} catch (Resources.NotFoundException e) {
resName = "unknown";
}
throwException(new IllegalArgumentException(
"No view found for id 0x"
+ Integer.toHexString(f.mContainerId) + " ("
+ resName
+ ") for fragment " + f));
}
}
f.mContainer = container;
//调用 Fragment 生命周期 onCreateView 方法
f.performCreateView(f.performGetLayoutInflater(
f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView != null) {
f.mInnerView = f.mView;
f.mView.setSaveFromParentEnabled(false);
if (container != null) {
//将Fragment 的布局添加到父布局中
container.addView(f.mView);
}
if (f.mHidden) {
f.mView.setVisibility(View.GONE);
}
//调用 Fragment 生命周期 onViewCreated 方法
f.onViewCreated(f.mView, f.mSavedFragmentState);
dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState,
false);
// Only animate the view if it is visible. This is done after
// dispatchOnFragmentViewCreated in case visibility is changed
f.mIsNewlyAdded = (f.mView.getVisibility() == View.VISIBLE)
&& f.mContainer != null;
} else {
f.mInnerView = null;
}
}
//调用 Fragment 生命周期 onActivityCreated 方法
f.performActivityCreated(f.mSavedFragmentState);
dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
// fall through
case Fragment.ACTIVITY_CREATED:
if (newState > Fragment.ACTIVITY_CREATED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
//调用 Fragment 生命周期 onStart 方法
f.performStart();
dispatchOnFragmentStarted(f, false);
}
// fall through
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
//调用 Fragment 生命周期 onResume 方法
f.performResume();
dispatchOnFragmentResumed(f, false);
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}
} else if (f.mState > newState) {
switch (f.mState) {
case Fragment.RESUMED:
if (newState < Fragment.RESUMED) {
if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);
//调用 Fragment 生命周期 onPause 方法
f.performPause();
dispatchOnFragmentPaused(f, false);
}
// fall through
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
//调用 Fragment 生命周期 onStop 方法
f.performStop();
dispatchOnFragmentStopped(f, false);
}
// fall through
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);
if (f.mView != null) {
// Need to save the current view state if not
// done already.
if (mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
saveFragmentViewState(f);
}
}
//调用 Fragment 生命周期 onDestroyView 方法
f.performDestroyView();
dispatchOnFragmentViewDestroyed(f, false);
if (f.mView != null && f.mContainer != null) {
// Stop any current animations:
f.mContainer.endViewTransition(f.mView);
f.mView.clearAnimation();
FragmentManagerImpl.AnimationOrAnimator anim = null;
// If parent is being removed, no need to handle child animations.
if (f.getParentFragment() == null || !f.getParentFragment().mRemoving) {
if (mCurState > Fragment.INITIALIZING && !mDestroyed
&& f.mView.getVisibility() == View.VISIBLE
&& f.mPostponedAlpha >= 0) {
anim = loadAnimation(f, transit, false,
transitionStyle);
}
f.mPostponedAlpha = 0;
if (anim != null) {
animateRemoveFragment(f, anim, newState);
}
f.mContainer.removeView(f.mView);
}
}
f.mContainer = null;
f.mView = null;
// Set here to ensure that Observers are called after
// the Fragment's view is set to null
f.mViewLifecycleOwner = null;
f.mViewLifecycleOwnerLiveData.setValue(null);
f.mInnerView = null;
f.mInLayout = false;
}
// fall through
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
if (mDestroyed) {
if (f.getAnimatingAway() != null) {
View v = f.getAnimatingAway();
f.setAnimatingAway(null);
v.clearAnimation();
} else if (f.getAnimator() != null) {
Animator animator = f.getAnimator();
f.setAnimator(null);
animator.cancel();
}
}
if (f.getAnimatingAway() != null || f.getAnimator() != null) {
f.setStateAfterAnimating(newState);
newState = Fragment.CREATED;
} else {
if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);
boolean beingRemoved = f.mRemoving && !f.isInBackStack();
if (beingRemoved || mNonConfig.shouldDestroy(f)) {
boolean shouldClear;
if (mHost instanceof ViewModelStoreOwner) {
shouldClear = mNonConfig.isCleared();
} else if (mHost.getContext() instanceof Activity) {
Activity activity = (Activity) mHost.getContext();
shouldClear = !activity.isChangingConfigurations();
} else {
shouldClear = true;
}
if (beingRemoved || shouldClear) {
mNonConfig.clearNonConfigState(f);
}
//调用 Fragment 生命周期 onDestroy 方法
f.performDestroy();
dispatchOnFragmentDestroyed(f, false);
} else {
f.mState = Fragment.INITIALIZING;
}
//调用 Fragment 生命周期 onDetach 方法
f.performDetach();
dispatchOnFragmentDetached(f, false);
if (!keepActive) {
if (beingRemoved || mNonConfig.shouldDestroy(f)) {
makeInactive(f);
} else {
f.mHost = null;
f.mParentFragment = null;
f.mFragmentManager = null;
if (f.mTargetWho != null) {
Fragment target = mActive.get(f.mTargetWho);
if (target != null && target.getRetainInstance()) {
// Only keep references to other retained Fragments
// to avoid developers accessing Fragments that
// are never coming back
f.mTarget = target;
}
}
}
}
}
}
}
}
if (f.mState != newState) {
Log.w(TAG, "moveToState: Fragment state for " + f + " not updated inline; "
+ "expected state " + newState + " found " + f.mState);
f.mState = newState;
}
}
我们看线Fragment#performResume
,其他生命周期类同
void performResume() {
mChildFragmentManager.noteStateNotSaved();
mChildFragmentManager.execPendingActions();
//把 mState 置为 RESUMED 方便执行 switch 的下面 RESUMED 分支
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();
mChildFragmentManager.execPendingActions();
}
执行FragmentManagerImpl#dispatchResume
分发事件
public void dispatchResume() {
mStateSaved = false;
mStopped = false;
dispatchStateChange(Fragment.RESUMED);
}
private void dispatchStateChange(int nextState) {
try {
mExecutingActions = true;
//改变状态
moveToState(nextState, false);
} finally {
mExecutingActions = false;
}
execPendingActions();
}
二、Fragment
public class Fragment implements ComponentCallbacks, OnCreateContextMenuListener, LifecycleOwner,
ViewModelStoreOwner, SavedStateRegistryOwner {
static final Object USE_DEFAULT_TRANSITION = new Object();
static final int INITIALIZING = 0; // Fragment尚未初始化或者已经被销毁
static final int CREATED = 1; // Fragment已被创建.
static final int ACTIVITY_CREATED = 2; // Fragment所在Activity已经创建成功
static final int STARTED = 3; // Fragment已经可见,但是还不可以接收点击事件
static final int RESUMED = 4; //Fragment已经可见并且可以接收点击事件
//当前 Fragment 的状态值
int mState = INITIALIZING;
// When instantiated from saved state, this is the saved state.
Bundle mSavedFragmentState;
SparseArray mSavedViewState;
@Nullable Boolean mSavedUserVisibleHint;
@NonNull
String mWho = UUID.randomUUID().toString();
Bundle mArguments;
Fragment mTarget;
String mTargetWho = null;
int mTargetRequestCode;
private Boolean mIsPrimaryNavigationFragment = null;
//是否被添加
boolean mAdded;
//是否被移除
boolean mRemoving;
boolean mFromLayout;
boolean mInLayout;
boolean mRestored;
boolean mPerformedCreateView;
int mBackStackNesting;
FragmentManagerImpl mFragmentManager;
//Fragmemt 绑定的对象,一半就是 Activity 和 Fragmen
FragmentHostCallback mHost;
// 管理子 Fragment
@NonNull
FragmentManagerImpl mChildFragmentManager = new FragmentManagerImpl();
//如果这个 Fragment 绑定的是另一个 Fragment,就需要设置这个值
Fragment mParentFragment;
// 容器 Fragment 的ID
int mFragmentId;
// 容器 View 的ID
int mContainerId;
String mTag;
//是否被隐藏
boolean mHidden;
//是否已经分离
boolean mDetached;
boolean mRetainInstance;
boolean mRetainInstanceChangedWhileDetached;
boolean mHasMenu;
boolean mMenuVisible = true;
private boolean mCalled;
// 父布局
ViewGroup mContainer;
//当前 Fragment 的布局
//在 onCreateView() 中返回一个 布局,
//然后在 FragmentManager 中拿到这个布局,
//添加到要绑定容器(Activity/Fragment)的 ViewGroup 中,然后设置相应的状态值
View mView;
// 真正保存状态的内部布局
View mInnerView;
boolean mDeferStart;
boolean mUserVisibleHint = true;
AnimationInfo mAnimationInfo;
Runnable mPostponedDurationRunnable = new Runnable() {
@Override
public void run() {
startPostponedEnterTransition();
}
};
boolean mIsNewlyAdded;
boolean mHiddenChanged;
float mPostponedAlpha;
LayoutInflater mLayoutInflater;
boolean mIsCreated;
Lifecycle.State mMaxState = Lifecycle.State.RESUMED;
LifecycleRegistry mLifecycleRegistry;
@Nullable FragmentViewLifecycleOwner mViewLifecycleOwner;
MutableLiveData mViewLifecycleOwnerLiveData = new MutableLiveData<>();
SavedStateRegistryController mSavedStateRegistryController;
@LayoutRes
private int mContentLayoutId;
}
三、提交任务
注意:执行 commitxxx()
方法之后,才正式执行fragment的生命周期。
执行FragmentTransaction
的实现类BackStackRecord
的commit
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);
}
//allowStateLoss :是否允许保存状态
int commitInternal(boolean allowStateLoss) {
if (mCommitted) throw new IllegalStateException("commit already called");
if (FragmentManagerImpl.DEBUG) {
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(this);
} else {
mIndex = -1;
}
//异步任务入队
mManager.enqueueAction(this, allowStateLoss);
return mIndex;
}
执行FragmentManagerImpl#enqueueAction
异步任务
public void enqueueAction(OpGenerator action, boolean allowStateLoss) {
//校验状态是否保存
if (!allowStateLoss) {
checkStateLoss();
}
synchronized (this) {
if (mDestroyed || mHost == null) {
if (allowStateLoss) {
//如果 allowStateLoss = true,直接退出。表示不会提交任务,丢弃保存的 state
return;
}
throw new IllegalStateException("Activity has been destroyed");
}
if (mPendingActions == null) {
mPendingActions = new ArrayList<>();
}
mPendingActions.add(action);
//发送任务
scheduleCommit();
}
}
校验状态
private void checkStateLoss() {
//在 onSaveInstanceState 保存状态后,isStateSaved == true
//当状态保存之后,在执行 commit 就会报此错误
if (isStateSaved()) {
throw new IllegalStateException(
"Can not perform this action after onSaveInstanceState");
}
}
public boolean isStateSaved() {
return mStateSaved || mStopped;
}
-
mStateSaved
状态置为true,是在Activity 执行onSaveInstanceState
保存状态之后。
protected void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
markFragmentsCreated();
mFragmentLifecycleRegistry.handleLifecycleEvent(Lifecycle.Event.ON_STOP);
//保存状态
Parcelable p = mFragments.saveAllState();
//序列化信息
if (p != null) {
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);
}
}
执行FragmentController#saveAllState
public Parcelable saveAllState() {
return mHost.mFragmentManager.saveAllState();
}
执行FragmentManagerImpl#saveAllState
Parcelable saveAllState() {.
forcePostponedTransactions();
endAnimatingAwayFragments();
execPendingActions();
//标志位至 true
mStateSaved = true;
if (mActive.isEmpty()) {
return null;
}
}
- 提交任务
void scheduleCommit() {
synchronized (this) {
boolean postponeReady =
mPostponedTransactions != null && !mPostponedTransactions.isEmpty();
boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
//通过 handler 发送异步消息
mHost.getHandler().removeCallbacks(mExecCommit);
mHost.getHandler().post(mExecCommit);
updateOnBackPressedCallbackEnabled();
}
}
}
接下来在 FragmentManagerImpl
类中看异步任务
Runnable mExecCommit = new Runnable() {
@Override
public void run() {
execPendingActions();
}
};
在主线程中更新 UI 嘛
public boolean execPendingActions() {
ensureExecReady(true);
boolean didSomething = false;
while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) {
mExecutingActions = true;
try {
removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop);
} finally {
cleanupExec();
}
didSomething = true;
}
updateOnBackPressedCallbackEnabled();
doPendingDeferredStart();
burpActive();
return didSomething;
}
private void removeRedundantOperationsAndExecute(ArrayList records,
ArrayList isRecordPop) {
if (records == null || records.isEmpty()) {
return;
}
if (isRecordPop == null || 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:
executePostponedTransaction(records, isRecordPop);
final int numRecords = records.size();
int startIndex = 0;
for (int recordNum = 0; recordNum < numRecords; recordNum++) {
final boolean canReorder = records.get(recordNum).mReorderingAllowed;
if (!canReorder) {
// execute all previous transactions
if (startIndex != recordNum) {
//这里将 Ops 过滤一遍,优化记录
executeOpsTogether(records, isRecordPop, startIndex, recordNum);
}
// execute all pop operations that don't allow reordering together or
// one add operation
int reorderingEnd = recordNum + 1;
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) {
executeOpsTogether(records, isRecordPop, startIndex, numRecords);
}
}
private void executeOpsTogether(ArrayList records,
ArrayList 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(mAdded);
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);
}
//真正处理的入口
executeOps(records, isRecordPop, startIndex, endIndex);
int postponeIndex = endIndex;
if (allowReordering) {
ArraySet addedFragments = new ArraySet<>();
addAddedFragments(addedFragments);
postponeIndex = postponePostponableTransactions(records, isRecordPop,
startIndex, endIndex, addedFragments);
//设置将要被移除的 Fragment 为不可见的最终实现
makeRemovedFragmentsInvisible(addedFragments);
}
if (postponeIndex != startIndex && allowReordering) {
// need to run something now
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex,
postponeIndex, true);
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) {
freeBackStackIndex(record.mIndex);
record.mIndex = -1;
}
record.runOnCommitRunnables();
}
if (addToBackStack) {
reportBackStackChanged();
}
}
然后在BackStackRecord#expandOps
看修改Ops 状态,这一步还没有真正处理状态
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: {
final Fragment f = op.mFragment;
final int containerId = f.mContainerId;
boolean alreadyAdded = false;
for (int i = added.size() - 1; i >= 0; i--) {
final Fragment old = added.get(i);
if (old.mContainerId == containerId) {
if (old == f) {
alreadyAdded = true;
} else {
// 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));
opNum++;
oldPrimaryNav = null;
}
//可以看到,替换也是通过删除实现的
final Op removeOp = new Op(OP_REMOVE, old);
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) {
mOps.remove(opNum);
opNum--;
} else {
op.mCmd = OP_ADD;
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));
opNum++;
// Will be set by the OP_SET_PRIMARY_NAV we inserted before when run
oldPrimaryNav = op.mFragment;
}
break;
}
}
return oldPrimaryNav;
}
将要被移除的 Fragment 为不可见的最终实现
private void makeRemovedFragmentsInvisible(ArraySet fragments) {
final int numAdded = fragments.size();
for (int i = 0; i < numAdded; i++) {
final Fragment fragment = fragments.valueAt(i);
if (!fragment.mAdded) {
final View view = fragment.requireView();
fragment.mPostponedAlpha = view.getAlpha();
//设为透明
view.setAlpha(0f);
}
}
}
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, mTransitionStyle);
}
switch (op.mCmd) {
case OP_ADD:
f.setNextAnim(op.mEnterAnim);
mManager.addFragment(f, false);
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.showFragment(f);
break;
case OP_DETACH:
f.setNextAnim(op.mExitAnim);
mManager.detachFragment(f);
break;
case OP_ATTACH:
f.setNextAnim(op.mEnterAnim);
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) {
// 回到之前生命周期变化的过程
mManager.moveToState(mManager.mCurState, true);
}
}
- 执行栈集合的入口
private static void executeOps(ArrayList records,
ArrayList 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();
}
}
}
- 在
FragmentTransaction
中可看到内部类Op
,Op
就是添加了状态和动画信息的 Fragment,mOps
就是栈中所有的 Fragment。
static final class Op {
int mCmd; //状态
Fragment mFragment;
int mEnterAnim;
int mExitAnim;
int mPopEnterAnim;
int mPopExitAnim;
Lifecycle.State mOldMaxState;
Lifecycle.State mCurrentMaxState;
Op() {
}
Op(int cmd, Fragment fragment) {
this.mCmd = cmd;
this.mFragment = fragment;
this.mOldMaxState = Lifecycle.State.RESUMED;
this.mCurrentMaxState = Lifecycle.State.RESUMED;
}
Op(int cmd, @NonNull Fragment fragment, Lifecycle.State state) {
this.mCmd = cmd;
this.mFragment = fragment;
this.mOldMaxState = fragment.mMaxState;
this.mCurrentMaxState = state;
}
}