这是我参与11月更文挑战的第18天,活动详情查看:2021最后一次更文挑战
框架的类图
-
FragmentActivity 是 Activity 支持 Fragment 的基础,
-
FragmentController是 FragmentActivity 和 FragmentManager 的中间桥接者,对 Fragment 的操作最终是分发到 FragmentManager 来处理;
-
FragmentManager负责对 Fragment 执行添加、移除或替换等操作,以及添加到返回堆栈。它的实现类 FragmentManagerImpl 是我们主要的分析对象;
-
FragmentHostCallback 是 FragmentManager 向 Fragment 宿主的回调接口
-
FragmentTransaction 是 Fragment 事务抽象类,它的实现类 BackStackRecord 是事务管理的主要分析对象。
生命周期
Fragment的几种状态
static final int INITIALIZING = 0;//初始状态,Fragment 未创建
static final int CREATED = 1;//已创建状态,Fragment 视图未创建
static final int ACTIVITY_CREATED = 2;//视图创建状态,Fragment 不可见
static final int STARTED = 3;//可见状态,Fragment 不处于前台
static final int RESUMED = 4;//前台状态,可接受用户交互
从FragmentActivity的oncreate中寻找生命周期的影子
protected void onCreate(@Nullable Bundle savedInstanceState) {
this.mFragments.attachHost((Fragment)null);
super.onCreate(savedInstanceState);
FragmentActivity.NonConfigurationInstances nc = (FragmentActivity.NonConfigurationInstances)this.getLastNonConfigurationInstance();
if (nc != null && nc.viewModelStore != null && this.mViewModelStore == null) {
this.mViewModelStore = nc.viewModelStore;
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable("android:support:fragments");
this.mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
if (savedInstanceState.containsKey("android:support:next_request_index")) {
this.mNextCandidateRequestIndex = savedInstanceState.getInt("android:support:next_request_index");
int[] requestCodes = savedInstanceState.getIntArray("android:support:request_indicies");
String[] fragmentWhos = savedInstanceState.getStringArray("android:support:request_fragment_who");
if (requestCodes != null && fragmentWhos != null && requestCodes.length == fragmentWhos.length) {
this.mPendingFragmentActivityResults = new SparseArrayCompat(requestCodes.length);
for(int i = 0; i < requestCodes.length; ++i) {
this.mPendingFragmentActivityResults.put(requestCodes[i], fragmentWhos[i]);
}
} else {
Log.w("FragmentActivity", "Invalid requestCode mapping in savedInstanceState.");
}
}
}
if (this.mPendingFragmentActivityResults == null) {
this.mPendingFragmentActivityResults = new SparseArrayCompat();
this.mNextCandidateRequestIndex = 0;
}
this.mFragments.dispatchCreate();
}
进入FragmentController类的 dispatchCreate方法
public void dispatchCreate() {
this.mHost.mFragmentManager.dispatchCreate();
}
mHost 是 FragmentHostCallback
private final FragmentHostCallback<?> mHost;
FragmentController类中有大量dispatch开头的生命周期方法,所有的方法最后都会走到 dispatchStateChange方法中。
private void dispatchStateChange(int nextState) {
try {
this.mExecutingActions = true;
this.moveToState(nextState, false);
} finally {
this.mExecutingActions = false;
}
this.execPendingActions();
}
进入moveToState方法
void moveToState(int newState, boolean always) {
if (this.mHost == null && newState != 0) {
throw new IllegalStateException("No activity");
} else if (always || newState != this.mCurState) {
this.mCurState = newState;
if (this.mActive != null) {
//mAdded 会将使用过的fragment都添加到集合中
int numAdded = this.mAdded.size();
int numActive;
for(numActive = 0; numActive < numAdded; ++numActive) {
Fragment f = (Fragment)this.mAdded.get(numActive);
//移动fragment到期望状态
this.moveFragmentToExpectedState(f);
}
numActive = this.mActive.size();
for(int i = 0; i < numActive; ++i) {
Fragment f = (Fragment)this.mActive.valueAt(i);
if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
//移动fragment到期望状态
this.moveFragmentToExpectedState(f);
}
}
this.startPendingDeferredFragments();
if (this.mNeedMenuInvalidate && this.mHost != null && this.mCurState == 4) {
this.mHost.onSupportInvalidateOptionsMenu();
this.mNeedMenuInvalidate = false;
}
}
}
}
进入moveFragmentToExpectedState 方法
void moveFragmentToExpectedState(Fragment f) {
if (f != null) {
int nextState = this.mCurState;
if (f.mRemoving) {
if (f.isInBackStack()) {
nextState = Math.min(nextState, 1);
} else {
nextState = Math.min(nextState, 0);
}
}
this.moveToState(f, nextState, f.getNextTransition(), f.getNextTransitionStyle(), false);
if (f.mView != null) {
Fragment underFragment = this.findFragmentUnder(f);
if (underFragment != null) {
View underView = underFragment.mView;
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) {
if (f.mPostponedAlpha > 0.0F) {
f.mView.setAlpha(f.mPostponedAlpha);
}
f.mPostponedAlpha = 0.0F;
f.mIsNewlyAdded = false;
FragmentManagerImpl.AnimationOrAnimator anim = this.loadAnimation(f, f.getNextTransition(), true, f.getNextTransitionStyle());
if (anim != null) {
setHWLayerAnimListenerIfAlpha(f.mView, anim);
if (anim.animation != null) {
f.mView.startAnimation(anim.animation);
} else {
anim.animator.setTarget(f.mView);
anim.animator.start();
}
}
}
}
if (f.mHiddenChanged) {
this.completeShowHideFragment(f);
}
}
}
进入moveToState方法(终于要开始进入生命周期的方法)
void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) {
if ((!f.mAdded || f.mDetached) && newState > 1) {
newState = 1;
}
if (f.mRemoving && newState > f.mState) {
if (f.mState == 0 && f.isInBackStack()) {
newState = 1;
} else {
newState = f.mState;
}
}
if (f.mDeferStart && f.mState < 3 && newState > 2) {
newState = 2;
}
if (f.mState <= newState) {
label297: {
if (f.mFromLayout && !f.mInLayout) {
return;
}
if (f.getAnimatingAway() != null || f.getAnimator() != null) {
f.setAnimatingAway((View)null);
f.setAnimator((Animator)null);
this.moveToState(f, f.getStateAfterAnimating(), 0, 0, true);
}
switch(f.mState) {
case 0:
if (newState > 0) {
if (DEBUG) {
Log.v("FragmentManager", "moveto CREATED: " + f);
}
if (f.mSavedFragmentState != null) {
f.mSavedFragmentState.setClassLoader(this.mHost.getContext().getClassLoader());
f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray("android:view_state");
f.mTarget = this.getFragment(f.mSavedFragmentState, "android:target_state");
if (f.mTarget != null) {
f.mTargetRequestCode = f.mSavedFragmentState.getInt("android:target_req_state", 0);
}
if (f.mSavedUserVisibleHint != null) {
f.mUserVisibleHint = f.mSavedUserVisibleHint;
f.mSavedUserVisibleHint = null;
} else {
f.mUserVisibleHint = f.mSavedFragmentState.getBoolean("android:user_visible_hint", true);
}
if (!f.mUserVisibleHint) {
f.mDeferStart = true;
if (newState > 2) {
newState = 2;
}
}
}
f.mHost = this.mHost;
f.mParentFragment = this.mParent;
f.mFragmentManager = this.mParent != null ? this.mParent.mChildFragmentManager : this.mHost.getFragmentManagerImpl();
if (f.mTarget != null) {
if (this.mActive.get(f.mTarget.mIndex) != f.mTarget) {
throw new IllegalStateException("Fragment " + f + " declared target fragment " + f.mTarget + " that does not belong to this FragmentManager!");
}
if (f.mTarget.mState < 1) {
this.moveToState(f.mTarget, 1, 0, 0, true);
}
}
this.dispatchOnFragmentPreAttached(f, this.mHost.getContext(), false);
f.mCalled = false;
f.onAttach(this.mHost.getContext());
if (!f.mCalled) {
throw new SuperNotCalledException("Fragment " + f + " did not call through to super.onAttach()");
}
if (f.mParentFragment == null) {
this.mHost.onAttachFragment(f);
} else {
f.mParentFragment.onAttachFragment(f);
}
//分发
this.dispatchOnFragmentAttached(f, this.mHost.getContext(), false);
//如果还没有创建
if (!f.mIsCreated) {
this.dispatchOnFragmentPreCreated(f, f.mSavedFragmentState, false);
f.performCreate(f.mSavedFragmentState);
this.dispatchOnFragmentCreated(f, f.mSavedFragmentState, false);
} else {
f.restoreChildFragmentState(f.mSavedFragmentState);
f.mState = 1;
}
f.mRetaining = false;
}
case 1:
this.ensureInflatedFragmentView(f);
if (newState > 1) {
if (DEBUG) {
Log.v("FragmentManager", "moveto ACTIVITY_CREATED: " + f);
}
if (!f.mFromLayout) {
ViewGroup container = null;
if (f.mContainerId != 0) {
if (f.mContainerId == -1) {
this.throwException(new IllegalArgumentException("Cannot create fragment " + f + " for a container view with no id"));
}
container = (ViewGroup)this.mContainer.onFindViewById(f.mContainerId);
if (container == null && !f.mRestored) {
String resName;
try {
resName = f.getResources().getResourceName(f.mContainerId);
} catch (NotFoundException var9) {
resName = "unknown";
}
this.throwException(new IllegalArgumentException("No view found for id 0x" + Integer.toHexString(f.mContainerId) + " (" + resName + ") for fragment " + f));
}
}
f.mContainer = container;
f.performCreateView(f.performGetLayoutInflater(f.mSavedFragmentState), container, f.mSavedFragmentState);
if (f.mView == null) {
f.mInnerView = null;
} else {
f.mInnerView = f.mView;
f.mView.setSaveFromParentEnabled(false);
if (container != null) {
container.addView(f.mView);
}
if (f.mHidden) {
f.mView.setVisibility(8);
}
f.onViewCreated(f.mView, f.mSavedFragmentState);
this.dispatchOnFragmentViewCreated(f, f.mView, f.mSavedFragmentState, false);
f.mIsNewlyAdded = f.mView.getVisibility() == 0 && f.mContainer != null;
}
}
f.performActivityCreated(f.mSavedFragmentState);
this.dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false);
if (f.mView != null) {
f.restoreViewState(f.mSavedFragmentState);
}
f.mSavedFragmentState = null;
}
case 2:
if (newState > 2) {
if (DEBUG) {
Log.v("FragmentManager", "moveto STARTED: " + f);
}
f.performStart();
this.dispatchOnFragmentStarted(f, false);
}
case 3:
break;
default:
break label297;
}
if (newState > 3) {
if (DEBUG) {
Log.v("FragmentManager", "moveto RESUMED: " + f);
}
f.performResume();
this.dispatchOnFragmentResumed(f, false);
f.mSavedFragmentState = null;
f.mSavedViewState = null;
}
}
} else if (f.mState > newState) {
switch(f.mState) {
case 4:
if (newState < 4) {
if (DEBUG) {
Log.v("FragmentManager", "movefrom RESUMED: " + f);
}
f.performPause();
this.dispatchOnFragmentPaused(f, false);
}
case 3:
if (newState < 3) {
if (DEBUG) {
Log.v("FragmentManager", "movefrom STARTED: " + f);
}
f.performStop();
this.dispatchOnFragmentStopped(f, false);
}
case 2:
if (newState < 2) {
if (DEBUG) {
Log.v("FragmentManager", "movefrom ACTIVITY_CREATED: " + f);
}
if (f.mView != null && this.mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
this.saveFragmentViewState(f);
}
f.performDestroyView();
this.dispatchOnFragmentViewDestroyed(f, false);
if (f.mView != null && f.mContainer != null) {
f.mContainer.endViewTransition(f.mView);
f.mView.clearAnimation();
FragmentManagerImpl.AnimationOrAnimator anim = null;
if (this.mCurState > 0 && !this.mDestroyed && f.mView.getVisibility() == 0 && f.mPostponedAlpha >= 0.0F) {
anim = this.loadAnimation(f, transit, false, transitionStyle);
}
f.mPostponedAlpha = 0.0F;
if (anim != null) {
this.animateRemoveFragment(f, anim, newState);
}
f.mContainer.removeView(f.mView);
}
f.mContainer = null;
f.mView = null;
f.mViewLifecycleOwner = null;
f.mViewLifecycleOwnerLiveData.setValue((Object)null);
f.mInnerView = null;
f.mInLayout = false;
}
case 1:
if (newState < 1) {
if (this.mDestroyed) {
if (f.getAnimatingAway() != null) {
View v = f.getAnimatingAway();
f.setAnimatingAway((View)null);
v.clearAnimation();
} else if (f.getAnimator() != null) {
Animator animator = f.getAnimator();
f.setAnimator((Animator)null);
animator.cancel();
}
}
if (f.getAnimatingAway() == null && f.getAnimator() == null) {
if (DEBUG) {
Log.v("FragmentManager", "movefrom CREATED: " + f);
}
if (!f.mRetaining) {
f.performDestroy();
this.dispatchOnFragmentDestroyed(f, false);
} else {
f.mState = 0;
}
f.performDetach();
this.dispatchOnFragmentDetached(f, false);
if (!keepActive) {
if (!f.mRetaining) {
this.makeInactive(f);
} else {
f.mHost = null;
f.mParentFragment = null;
f.mFragmentManager = null;
}
}
} else {
f.setStateAfterAnimating(newState);
newState = 1;
}
}
}
}
if (f.mState != newState) {
Log.w("FragmentManager", "moveToState: Fragment state for " + f + " not updated inline; " + "expected state " + newState + " found " + f.mState);
f.mState = newState;
}
}
第一次进入的时候,执行 f.onAttach(this.mHost.getContext());
public void onAttach(Context context) {
this.mCalled = true;
Activity hostActivity = this.mHost == null ? null : this.mHost.getActivity();
if (hostActivity != null) {
this.mCalled = false;
this.onAttach(hostActivity);
}
}
onAttach执行完之后就进入dispatchOnFragmentAttached方法
void dispatchOnFragmentAttached(@NonNull Fragment f, @NonNull Context context, boolean onlyRecursive) {
if (this.mParent != null) {
//获取父类的FragmentManager
FragmentManager parentManager = this.mParent.getFragmentManager();
if (parentManager instanceof FragmentManagerImpl) {
((FragmentManagerImpl)parentManager).dispatchOnFragmentAttached(f, context, true);
}
}
Iterator var6 = this.mLifecycleCallbacks.iterator();
while(true) {
FragmentManagerImpl.FragmentLifecycleCallbacksHolder holder;
do {
if (!var6.hasNext()) {
return;
}
holder = (FragmentManagerImpl.FragmentLifecycleCallbacksHolder)var6.next();
} while(onlyRecursive && !holder.mRecursive);
holder.mCallback.onFragmentAttached(this, f, context);
}
}
继续执行,如果还没有创建的话会执行performCreate(f.mSavedFragmentState)方法
void performCreate(Bundle savedInstanceState) {
if (this.mChildFragmentManager != null) {
this.mChildFragmentManager.noteStateNotSaved();
}
//把状态变成create,目的是下一个case能够进入方法
this.mState = 1;
this.mCalled = false;
//回掉onCreate 方法
this.onCreate(savedInstanceState);
this.mIsCreated = true;
if (!this.mCalled) {
throw new SuperNotCalledException("Fragment " + this + " did not call through to super.onCreate()");
} else {
this.mLifecycleRegistry.handleLifecycleEvent(Event.ON_CREATE);
}
}
会回掉oncreate方法。
进入create状态
会执行performCreateView 方法
f.performCreateView(f.performGetLayoutInflater(f.mSavedFragmentState), container, f.mSavedFragmentState);
进入performCreateView方法
void performCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
if (this.mChildFragmentManager != null) {
this.mChildFragmentManager.noteStateNotSaved();
}
this.mPerformedCreateView = true;
this.mViewLifecycleOwner = new LifecycleOwner() {
public Lifecycle getLifecycle() {
if (Fragment.this.mViewLifecycleRegistry == null) {
Fragment.this.mViewLifecycleRegistry = new LifecycleRegistry(Fragment.this.mViewLifecycleOwner);
}
return Fragment.this.mViewLifecycleRegistry;
}
};
this.mViewLifecycleRegistry = null;
//创建view
this.mView = this.onCreateView(inflater, container, savedInstanceState);
if (this.mView != null) {
this.mViewLifecycleOwner.getLifecycle();
this.mViewLifecycleOwnerLiveData.setValue(this.mViewLifecycleOwner);
} else {
if (this.mViewLifecycleRegistry != null) {
throw new IllegalStateException("Called getViewLifecycleOwner() but onCreateView() returned null");
}
this.mViewLifecycleOwner = null;
}
}
执行完之后View就已经被创建出来了。
继续往下执行会有一个performActivityCreated(f.mSavedFragmentState)被调用
void performActivityCreated(Bundle savedInstanceState) {
if (this.mChildFragmentManager != null) {
this.mChildFragmentManager.noteStateNotSaved();
}
//将状态赋值
this.mState = 2;
this.mCalled = false;
this.onActivityCreated(savedInstanceState);
if (!this.mCalled) {
throw new SuperNotCalledException("Fragment " + this + " did not call through to super.onActivityCreated()");
} else {
if (this.mChildFragmentManager != null) {
this.mChildFragmentManager.dispatchActivityCreated();
}
}
}
执行onActivityCreated方法
状态为ACTIVITY_CREATED继续执行代码 执行f.performStart();
void performStart() {
if (this.mChildFragmentManager != null) {
this.mChildFragmentManager.noteStateNotSaved();
this.mChildFragmentManager.execPendingActions();
}
//修改状态的值
this.mState = 3;
this.mCalled = false;
this.onStart();
if (!this.mCalled) {
throw new SuperNotCalledException("Fragment " + this + " did not call through to super.onStart()");
} else {
if (this.mChildFragmentManager != null) {
this.mChildFragmentManager.dispatchStart();
}
this.mLifecycleRegistry.handleLifecycleEvent(Event.ON_START);
if (this.mView != null) {
this.mViewLifecycleRegistry.handleLifecycleEvent(Event.ON_START);
}
}
}
执行onStart()方法
状态为STARTED,继续往下,执行f.performResume()方法
void performResume() {
if (this.mChildFragmentManager != null) {
this.mChildFragmentManager.noteStateNotSaved();
this.mChildFragmentManager.execPendingActions();
}
//给状态赋值
this.mState = 4;
this.mCalled = false;
this.onResume();
if (!this.mCalled) {
throw new SuperNotCalledException("Fragment " + this + " did not call through to super.onResume()");
} else {
if (this.mChildFragmentManager != null) {
this.mChildFragmentManager.dispatchResume();
this.mChildFragmentManager.execPendingActions();
}
this.mLifecycleRegistry.handleLifecycleEvent(Event.ON_RESUME);
if (this.mView != null) {
this.mViewLifecycleRegistry.handleLifecycleEvent(Event.ON_RESUME);
}
}
}
执行onResume的生命周期的方法。
至此fragment就已经显示出来了。
fragment退出时会执行下面的代码
else if (f.mState > newState) {
switch(f.mState) {
case 4:
if (newState < 4) {
if (DEBUG) {
Log.v("FragmentManager", "movefrom RESUMED: " + f);
}
f.performPause();
this.dispatchOnFragmentPaused(f, false);
}
case 3:
if (newState < 3) {
if (DEBUG) {
Log.v("FragmentManager", "movefrom STARTED: " + f);
}
f.performStop();
this.dispatchOnFragmentStopped(f, false);
}
case 2:
if (newState < 2) {
if (DEBUG) {
Log.v("FragmentManager", "movefrom ACTIVITY_CREATED: " + f);
}
if (f.mView != null && this.mHost.onShouldSaveFragmentState(f) && f.mSavedViewState == null) {
this.saveFragmentViewState(f);
}
f.performDestroyView();
this.dispatchOnFragmentViewDestroyed(f, false);
if (f.mView != null && f.mContainer != null) {
f.mContainer.endViewTransition(f.mView);
f.mView.clearAnimation();
FragmentManagerImpl.AnimationOrAnimator anim = null;
if (this.mCurState > 0 && !this.mDestroyed && f.mView.getVisibility() == 0 && f.mPostponedAlpha >= 0.0F) {
anim = this.loadAnimation(f, transit, false, transitionStyle);
}
f.mPostponedAlpha = 0.0F;
if (anim != null) {
this.animateRemoveFragment(f, anim, newState);
}
f.mContainer.removeView(f.mView);
}
f.mContainer = null;
f.mView = null;
f.mViewLifecycleOwner = null;
f.mViewLifecycleOwnerLiveData.setValue((Object)null);
f.mInnerView = null;
f.mInLayout = false;
}
case 1:
if (newState < 1) {
if (this.mDestroyed) {
if (f.getAnimatingAway() != null) {
View v = f.getAnimatingAway();
f.setAnimatingAway((View)null);
v.clearAnimation();
} else if (f.getAnimator() != null) {
Animator animator = f.getAnimator();
f.setAnimator((Animator)null);
animator.cancel();
}
}
if (f.getAnimatingAway() == null && f.getAnimator() == null) {
if (DEBUG) {
Log.v("FragmentManager", "movefrom CREATED: " + f);
}
if (!f.mRetaining) {
f.performDestroy();
this.dispatchOnFragmentDestroyed(f, false);
} else {
f.mState = 0;
}
f.performDetach();
this.dispatchOnFragmentDetached(f, false);
if (!keepActive) {
if (!f.mRetaining) {
this.makeInactive(f);
} else {
f.mHost = null;
f.mParentFragment = null;
f.mFragmentManager = null;
}
}
} else {
f.setStateAfterAnimating(newState);
newState = 1;
}
}
}
}
依次调用: f.performPause() -》this.onPause() -》f.performStop() -》 this.onStop() -》f.performDestroyView() -》this.onDestroyView() -》f.performDestroy()-》this.onDestroy()
自此fragment的生命周期的大致流程就走过路一遍。
小结
常见操作
添加操作
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(XXXX)
transaction.commit()
进入add方法
public FragmentTransaction add(int containerViewId, Fragment fragment, @Nullable String tag) {
this.doAddOp(containerViewId, fragment, tag, 1);
return this;
}
进入doAddOp方法
private void doAddOp(int containerViewId, Fragment fragment, @Nullable String tag, int opcmd) {
Class fragmentClass = fragment.getClass();
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.");
} else {
fragment.mFragmentManager = this.mManager;
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;
}
if (containerViewId != 0) {
if (containerViewId == -1) {
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;
}
this.addOp(new BackStackRecord.Op(opcmd, fragment));
}
}
Op类的相关介绍
static final class Op {
int cmd;
Fragment fragment;
int enterAnim;
int exitAnim;
int popEnterAnim;
int popExitAnim;
Op() {
}
Op(int cmd, Fragment fragment) {
this.cmd = cmd;
this.fragment = fragment;
}
}
进入addOp 方法
void addOp(BackStackRecord.Op op) {
this.mOps.add(op);
op.enterAnim = this.mEnterAnim;
op.exitAnim = this.mExitAnim;
op.popEnterAnim = this.mPopEnterAnim;
op.popExitAnim = this.mPopExitAnim;
}
commit提交
public int commit() {
return this.commitInternal(false);//状态不掉时
}
进入commitInternal方法
int commitInternal(boolean allowStateLoss) {
if (this.mCommitted) {
throw new IllegalStateException("commit already called");
} else {
if (FragmentManagerImpl.DEBUG) {
Log.v("FragmentManager", "Commit: " + this);
LogWriter logw = new LogWriter("FragmentManager");
PrintWriter pw = new PrintWriter(logw);
this.dump(" ", (FileDescriptor)null, pw, (String[])null);
pw.close();
}
//提交完成
this.mCommitted = true;
//是否存在栈操作
if (this.mAddToBackStack) {
this.mIndex = this.mManager.allocBackStackIndex(this);
} else {
this.mIndex = -1;
}
this.mManager.enqueueAction(this, allowStateLoss);
return this.mIndex;
}
}
进入enqueueAction方法
public void enqueueAction(FragmentManagerImpl.OpGenerator action, boolean allowStateLoss) {
if (!allowStateLoss) {
this.checkStateLoss();
}
synchronized(this) {
if (!this.mDestroyed && this.mHost != null) {
if (this.mPendingActions == null) {
this.mPendingActions = new ArrayList();
}
//添加到存放事物操作的集合
this.mPendingActions.add(action);
//执行提交
this.scheduleCommit();
} else if (!allowStateLoss) {
throw new IllegalStateException("Activity has been destroyed");
}
}
}
scheduleCommit执行提交
void scheduleCommit() {
synchronized(this) {
boolean postponeReady = this.mPostponedTransactions != null && !this.mPostponedTransactions.isEmpty();
boolean pendingReady = this.mPendingActions != null && this.mPendingActions.size() == 1;
if (postponeReady || pendingReady) {
this.mHost.getHandler().removeCallbacks(this.mExecCommit);
this.mHost.getHandler().post(this.mExecCommit);
}
}
}
mExecCommit是一个Runnable对象,里面执行execPendingActions方法
Runnable mExecCommit = new Runnable() {
public void run() {
FragmentManagerImpl.this.execPendingActions();
}
};
执行execPendingActions方法
public boolean execPendingActions() {
this.ensureExecReady(true);
boolean didSomething;
for(didSomething = false; this.generateOpsForPendingActions(this.mTmpRecords, this.mTmpIsPop); didSomething = true) {
this.mExecutingActions = true;
try {
//裁剪操作 this.removeRedundantOperationsAndExecute(this.mTmpRecords, this.mTmpIsPop);
} finally {
this.cleanupExec();
}
}
this.doPendingDeferredStart();
this.burpActive();
return didSomething;
}
generateOpsForPendingActions()这个方法是重新组装一下数据,添加一个是否放入栈的标签。
进入removeRedundantOperationsAndExecute方法
private void removeRedundantOperationsAndExecute(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop) {
if (records != null && !records.isEmpty()) {
if (isRecordPop != null && records.size() == isRecordPop.size()) {
this.executePostponedTransaction(records, isRecordPop);
int numRecords = records.size();
int startIndex = 0;
for(int recordNum = 0; recordNum < numRecords; ++recordNum) {
boolean canReorder = ((BackStackRecord)records.get(recordNum)).mReorderingAllowed;
if (!canReorder) {
if (startIndex != recordNum) {
//执行操作
this.executeOpsTogether(records, isRecordPop, startIndex, recordNum);
}
int reorderingEnd = recordNum + 1;
if ((Boolean)isRecordPop.get(recordNum)) {
while(reorderingEnd < numRecords && (Boolean)isRecordPop.get(reorderingEnd) && !((BackStackRecord)records.get(reorderingEnd)).mReorderingAllowed) {
++reorderingEnd;
}
}
this.executeOpsTogether(records, isRecordPop, recordNum, reorderingEnd);
startIndex = reorderingEnd;
recordNum = reorderingEnd - 1;
}
}
if (startIndex != numRecords) {
this.executeOpsTogether(records, isRecordPop, startIndex, numRecords);
}
} else {
throw new IllegalStateException("Internal error with the back stack records");
}
}
}
进入executeOpsTogether方法
private void executeOpsTogether(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
boolean allowReordering = ((BackStackRecord)records.get(startIndex)).mReorderingAllowed;
boolean addToBackStack = false;
if (this.mTmpAddedFragments == null) {
this.mTmpAddedFragments = new ArrayList();
} else {
this.mTmpAddedFragments.clear();
}
this.mTmpAddedFragments.addAll(this.mAdded);
Fragment oldPrimaryNav = this.getPrimaryNavigationFragment();
int postponeIndex;
for(postponeIndex = startIndex; postponeIndex < endIndex; ++postponeIndex) {
BackStackRecord record = (BackStackRecord)records.get(postponeIndex);
boolean isPop = (Boolean)isRecordPop.get(postponeIndex);
if (!isPop) {
oldPrimaryNav = record.expandOps(this.mTmpAddedFragments, oldPrimaryNav);
} else {
oldPrimaryNav = record.trackAddedFragmentsInPop(this.mTmpAddedFragments, oldPrimaryNav);
}
addToBackStack = addToBackStack || record.mAddToBackStack;
}
this.mTmpAddedFragments.clear();
if (!allowReordering) {
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, endIndex, false);
}
executeOps(records, isRecordPop, startIndex, endIndex);
postponeIndex = endIndex;
if (allowReordering) {
ArraySet<Fragment> addedFragments = new ArraySet();
this.addAddedFragments(addedFragments);
postponeIndex = this.postponePostponableTransactions(records, isRecordPop, startIndex, endIndex, addedFragments);
this.makeRemovedFragmentsInvisible(addedFragments);
}
if (postponeIndex != startIndex && allowReordering) {
FragmentTransition.startTransitions(this, records, isRecordPop, startIndex, postponeIndex, true);
this.moveToState(this.mCurState, true);
}
for(int recordNum = startIndex; recordNum < endIndex; ++recordNum) {
BackStackRecord record = (BackStackRecord)records.get(recordNum);
boolean isPop = (Boolean)isRecordPop.get(recordNum);
if (isPop && record.mIndex >= 0) {
this.freeBackStackIndex(record.mIndex);
record.mIndex = -1;
}
record.runOnCommitRunnables();
}
if (addToBackStack) {
this.reportBackStackChanged();
}
}
进入expandOps方法
Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) {
for(int opNum = 0; opNum < this.mOps.size(); ++opNum) {
BackStackRecord.Op op = (BackStackRecord.Op)this.mOps.get(opNum);
switch(op.cmd) {
case 1:
case 7:
added.add(op.fragment);
break;
case 2:
Fragment f = op.fragment;
int containerId = f.mContainerId;
boolean alreadyAdded = false;
int i = added.size() - 1;
for(; i >= 0; --i) {
Fragment old = (Fragment)added.get(i);
if (old.mContainerId == containerId) {
if (old == f) {
alreadyAdded = true;
} else {
if (old == oldPrimaryNav) {
this.mOps.add(opNum, new BackStackRecord.Op(9, old));
++opNum;
oldPrimaryNav = null;
}
BackStackRecord.Op removeOp = new BackStackRecord.Op(3, old);
removeOp.enterAnim = op.enterAnim;
removeOp.popEnterAnim = op.popEnterAnim;
removeOp.exitAnim = op.exitAnim;
removeOp.popExitAnim = op.popExitAnim;
this.mOps.add(opNum, removeOp);
added.remove(old);
++opNum;
}
}
}
if (alreadyAdded) {
this.mOps.remove(opNum);
--opNum;
} else {
op.cmd = 1;
added.add(f);
}
break;
case 3:
case 6:
added.remove(op.fragment);
if (op.fragment == oldPrimaryNav) {
this.mOps.add(opNum, new BackStackRecord.Op(9, op.fragment));
++opNum;
oldPrimaryNav = null;
}
case 4:
case 5:
default:
break;
case 8:
this.mOps.add(opNum, new BackStackRecord.Op(9, oldPrimaryNav));
++opNum;
oldPrimaryNav = op.fragment;
}
}
return oldPrimaryNav;
}
所有的操作都变成路add操作
继续往下,进入executeOps方法
private static void executeOps(ArrayList<BackStackRecord> records, ArrayList<Boolean> isRecordPop, int startIndex, int endIndex) {
//循环取事物
for(int i = startIndex; i < endIndex; ++i) {
BackStackRecord record = (BackStackRecord)records.get(i);
boolean isPop = (Boolean)isRecordPop.get(i);
if (isPop) {
record.bumpBackStackNesting(-1);
boolean moveToState = i == endIndex - 1;
record.executePopOps(moveToState);
} else {
record.bumpBackStackNesting(1);
record.executeOps();
}
}
}
进入executeOps 方法
void executeOps() {
int numOps = this.mOps.size();
for(int opNum = 0; opNum < numOps; ++opNum) {
BackStackRecord.Op op = (BackStackRecord.Op)this.mOps.get(opNum);
Fragment f = op.fragment;
if (f != null) {
f.setNextTransition(this.mTransition, this.mTransitionStyle);
}
switch(op.cmd) {
case 1:
f.setNextAnim(op.enterAnim);
this.mManager.addFragment(f, false);
break;
case 2:
default:
throw new IllegalArgumentException("Unknown cmd: " + op.cmd);
case 3:
f.setNextAnim(op.exitAnim);
this.mManager.removeFragment(f);
break;
case 4:
f.setNextAnim(op.exitAnim);
this.mManager.hideFragment(f);
break;
case 5:
f.setNextAnim(op.enterAnim);
this.mManager.showFragment(f);
break;
case 6:
f.setNextAnim(op.exitAnim);
this.mManager.detachFragment(f);
break;
case 7:
f.setNextAnim(op.enterAnim);
this.mManager.attachFragment(f);
break;
case 8:
this.mManager.setPrimaryNavigationFragment(f);
break;
case 9:
this.mManager.setPrimaryNavigationFragment((Fragment)null);
}
if (!this.mReorderingAllowed && op.cmd != 1 && f != null) {
this.mManager.moveFragmentToExpectedState(f);
}
}
if (!this.mReorderingAllowed) {
this.mManager.moveToState(this.mManager.mCurState, true);
}
}
找一个添加Fragment的方法分析一下
public void addFragment(Fragment fragment, boolean moveToStateNow) {
if (DEBUG) {
Log.v("FragmentManager", "add: " + fragment);
}
this.makeActive(fragment);
if (!fragment.mDetached) {//没有销毁
if (this.mAdded.contains(fragment)) {
throw new IllegalStateException("Fragment already added: " + fragment);
}
synchronized(this.mAdded) {
this.mAdded.add(fragment);//添加到可用集合
}
fragment.mAdded = true;
fragment.mRemoving = false;
if (fragment.mView == null) {
fragment.mHiddenChanged = false;
}
if (fragment.mHasMenu && fragment.mMenuVisible) {
this.mNeedMenuInvalidate = true;
}
if (moveToStateNow) {
this.moveToState(fragment);//走生命周期的方法
}
}
}
到此添加的操作基本算走完。
常见的OP的值
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;
小结
remove,replace,hide,show 和add有点类似,所以暂时不做分析。
回退栈
public FragmentTransaction addToBackStack(@Nullable String name) {
if (!this.mAllowAddToBackStack) {
throw new IllegalStateException("This FragmentTransaction is not allowed to be added to the back stack.");
} else {
//设置一个标签
this.mAddToBackStack = true;
this.mName = name;
return this;
}
}
提交的时候
int commitInternal(boolean allowStateLoss) {
if (this.mCommitted) {
throw new IllegalStateException("commit already called");
} else {
if (FragmentManagerImpl.DEBUG) {
Log.v("FragmentManager", "Commit: " + this);
LogWriter logw = new LogWriter("FragmentManager");
PrintWriter pw = new PrintWriter(logw);
this.dump(" ", (FileDescriptor)null, pw, (String[])null);
pw.close();
}
this.mCommitted = true;
if (this.mAddToBackStack) {
this.mIndex = this.mManager.allocBackStackIndex(this);
} else {
this.mIndex = -1;
}
this.mManager.enqueueAction(this, allowStateLoss);
return this.mIndex;
}
}
调用mManager.allocBackStackIndex(this);
public int allocBackStackIndex(BackStackRecord bse) {
synchronized(this) {
int index;
if (this.mAvailBackStackIndices != null && this.mAvailBackStackIndices.size() > 0) {
index = (Integer)this.mAvailBackStackIndices.remove(this.mAvailBackStackIndices.size() - 1);
if (DEBUG) {
Log.v("FragmentManager", "Adding back stack index " + index + " with " + bse);
}
this.mBackStackIndices.set(index, bse);
return index;
} else {
if (this.mBackStackIndices == null) {
this.mBackStackIndices = new ArrayList();
}
index = this.mBackStackIndices.size();
if (DEBUG) {
Log.v("FragmentManager", "Setting back stack index " + index + " to " + bse);
}
this.mBackStackIndices.add(bse);
return index;
}
}
}
释放
public void freeBackStackIndex(int index) {
synchronized(this) {
this.mBackStackIndices.set(index, (Object)null);
if (this.mAvailBackStackIndices == null) {
this.mAvailBackStackIndices = new ArrayList();
}
if (DEBUG) {
Log.v("FragmentManager", "Freeing back stack index " + index);
}
this.mAvailBackStackIndices.add(index);
}
}
设置
public void setBackStackIndex(int index, BackStackRecord bse) {
synchronized(this) {
if (this.mBackStackIndices == null) {
this.mBackStackIndices = new ArrayList();
}
int N = this.mBackStackIndices.size();
if (index < N) {
if (DEBUG) {
Log.v("FragmentManager", "Setting back stack index " + index + " to " + bse);
}
this.mBackStackIndices.set(index, bse);
} else {
while(N < index) {
this.mBackStackIndices.add((Object)null);
if (this.mAvailBackStackIndices == null) {
this.mAvailBackStackIndices = new ArrayList();
}
if (DEBUG) {
Log.v("FragmentManager", "Adding available back stack index " + N);
}
this.mAvailBackStackIndices.add(N);
++N;
}
if (DEBUG) {
Log.v("FragmentManager", "Adding back stack index " + index + " with " + bse);
}
this.mBackStackIndices.add(bse);
}
}
}
回退栈的原理:
首次添加fragment的时候先向mBackStackIndices添加,当时释放的时候会通过索引将mBackStackIndices位置设置为null,同时把索引存到mAvailBackStackIndices中,下次添加的时候先从mAvailBackStackIndices拿索引值,给mBackStackIndices对应的索引位置设置值
这样操作提高的内存的复用,避免频繁的创建。
常见面试题
怎么去管理Fragment?
通过getFragmentManager()方法获取FragmentManager实例 调用findFragmentById()或者findFragmentByTag()方法来获取一个Fragment 调用popBackStack方法将Fragment从后退站中弹出 调用addOnBackChangedListener()方法注册监听器,用于监听后退站的变化
执行Fragment的事务,事务有什么特点?
每个事务都表示执行一组变化,这些变化包括add()、remove()、replace()、addToBackStack()、setCustomAnimations、setTransition事务要生效必须调用commit,commit并不会立即执行,只能等待UI主线程空闲时才能执行也可以调用executePendingTransactions立即生效提交事务,commit在调用时机是Activity状态保存之前进行,也就是说如果在离开Activity是进行提交事务的操作,系统就会抛出异常
简述Fragment生命周期,常用的回调方法有几个?
onActtch:初始化Fragment 事件回调接口 onCreate:初始化参数 onCreateView:为Fragment绑定布局 onViewCreated:进行控件实例化操作 onPause:在用户离开Fragment是所进行的一些数据持久化操作 当Activity的onCreate方法被回调时会导致fragment方法的onAttach()、onCreate()、onCreateView()、onActivityCreate() 被连续回调
Activity和Fragment 的 onActivityForResult 回调?
- 当在Fragment里面调用startActivityForResult的时候 Activity和Fragment里面的onActivityForResult都会回调,只不过Fragment里面回调的requestCode是正确的
- 当在Fragment里面调用getActivity().startActivityForResult的时候,就会回调Activity里面的onActivityForResult
- 当Fragment存在多层嵌套的情况,内层的Fragment调用startActivityForResult的时候,onActivityForResult方法不回调,此时需要创建一个BaseActivity复写它的onActivityResult方法
Fragment的getActivity方法返回null的原因:
如果系统内存不足、或者切换横竖屏、或者app长时间在后台运行,Activity都可能会被系统回收,但是Fragment并不会随着Activity的回收而被回收,从而导致Fragment丢失对应的Activity。这里,假设我们继承于FragmentActivity的类为MainActivity,其中用到的Fragment为FragmentA。 app发生的变化为:某种原因系统回收MainActivity——FragmentA被保存状态未被回收——再次点击app进入——首先加载的是未被回收的FragmentA的页面——由于MainActivity被回收,系统会重启MainActivity,FragmentA也会被再次加载——页面出现混乱,因为一层未回收的FragmentA覆盖在其上面——(假如FragmentA使用到了getActivity()方法)会报NullPointerException:
方案1:在使用Fragment的Activity中重写onSaveInstanceState方法,将super.onSaveInstanceState(outState)注释掉,让其不再保存Fragment的状态,达到其随着MainActivity一起被回收的效果。
方案2:在再次启动Activity的时候,在onCreate方法中将之前保存过的fragment状态清除
方案3:避免使用getActivity方法得到activity,如果确实需要使用上下文,可以写一个类MyApplication继承Application,并且写一个方法getContext(),返回一个Context 对象。
请简述Fragment的意义?
- Fragment是Activity界面的一部分,Fragment是依附于Activity之上的;
- Activity是Fragment的基础,Fragment是Activity的延续和发展
- 一个Activity可以有多个Fragment,一个Fragment也可以被多个Activity重复使用;
- 一个Fragment除了Activity处于onResume状态下,他可以自己灵活的控制自己的生命周期,其他状态下,其生命周期都是由Activity所决定的;
- Fragment的出现增强了UI界面布局的灵活性,可以实现动态的改变UI布局;