相信大家平时用到很多Fragment, 手机平板的代码共用,各种东西的复用,用Fragment也很方便。如今Fragment遍布在我们的APP里面,今天此文将讲解Activity是如何Fragment机制联动的,以及各个生命周期是如何走的,因为,说实话,Fragment的生命周期足够复杂,我们需要知道它的各个生命周期是如何被调用的。
今天涉及到的类:(本文基于Android8.1源码)
// Activity类, AMS控制的生命周期都是回调给Activity
frameworks/base/core/java/android/app/Activity.java
// Fragment,被实现对象,被回调生命周期对象
frameworks/base/core/java/android/app/Fragment.java
// FragmentController 其实是一个代理类,代理FragmentManager那些方法 frameworks/base/core/java/android/app/FragmentController.java
// FragmentHostCallback 这是一个抽象类,需要主体实现,里面实现一些Fragment机制中所不能实现的功能,比如请求权限,这些都需要主体来实现
frameworks/base/core/java/android/app/FragmentHostCallback.java
// Fragment的管理类,被FragmentHostCallback持有,负责控制Fragment的状态,真正做操作的类
frameworks/base/core/java/android/app/FragmentManager.java
我们从Activity下手, 从getFragmentManager来看,我们是去从FragmentController中获取的FragmentManager。
public class Activity extends... { final FragmentController mFragments = FragmentController.createController(new HostCallbacks()); /** * Return the FragmentManager for interacting with fragments associated * with this activity. */ public FragmentManager getFragmentManager() { return mFragments.getFragmentManager(); } // 在这里实现FragmentHostCallback所无法实现的那些功能,列如activituy跳转的数据结果等 class HostCallbacks extends FragmentHostCallback<Activity> { ... } }
从FragmentController的源码可以看到,构造方法的参数为: FragmentHostCallback且,这是唯一的变量。 然后其他方法都是代理, 都调用的是mHost.mFragmentManager中的同名方法。 代码如下:
public class FragmentController { private final FragmentHostCallback<?> mHost; /** * Returns a {@link FragmentController}. */ public static final FragmentController createController(FragmentHostCallback<?> callbacks) { return new FragmentController(callbacks); } private FragmentController(FragmentHostCallback<?> callbacks) { mHost = callbacks; } // 调用mHost.mFragmentManager的同名方法 public void dispatchResume() { mHost.mFragmentManager.dispatchResume(); } public void dispatchPause() { mHost.mFragmentManager.dispatchPause(); } .... }
我们在前面看Activity初始化FragmentControl的时候,会传FragmentHostCallback类,
那么 mHost.mFragmentManager
是什么呢,其是FragmentManagerImpl类,这个是FragmentManger的一个内部类,也继承于FragmentManger, 并且实现了LayoutInflaterFactory接口。是个做实事的家伙。
public abstract class FragmentHostCallback<E> extends FragmentContainer { private final Activity mActivity; final Context mContext; private final Handler mHandler; final int mWindowAnimations; final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl(); /** The loader managers for individual fragments [i.e. Fragment#getLoaderManager()] */ private SimpleArrayMap<String, LoaderManager> mAllLoaderManagers; /** Whether or not fragment loaders should retain their state */ private boolean mRetainLoaders; /** The loader manger for the fragment host [i.e. Activity#getLoaderManager()] */ private LoaderManagerImpl mLoaderManager; private boolean mCheckedForLoaderManager; /** Whether or not the fragment host loader manager was started */ private boolean mLoadersStarted; public FragmentHostCallback(Context context, Handler handler, int windowAnimations) { this(null /*activity*/, context, handler, windowAnimations); } ... }
FragmentManagerImpl类是最核心的类,Fragment由其管理,各种安全检查也由其做。代码如下
final class FragmentManagerImpl extends FragmentManager implements LayoutInflater.Factory2 { static final String TAG = "FragmentManager"; ArrayList<OpGenerator> mPendingActions; boolean mExecutingActions; int mNextFragmentIndex = 0; SparseArray<Fragment> mActive; final ArrayList<Fragment> mAdded = new ArrayList<>(); ArrayList<BackStackRecord> mBackStack; ArrayList<Fragment> mCreatedMenus; // Must be accessed while locked. ArrayList<BackStackRecord> mBackStackIndices; ArrayList<Integer> mAvailBackStackIndices; ArrayList<OnBackStackChangedListener> mBackStackChangeListeners; final CopyOnWriteArrayList<Pair<FragmentLifecycleCallbacks, Boolean>> mLifecycleCallbacks = new CopyOnWriteArrayList<>(); int mCurState = Fragment.INITIALIZING; FragmentHostCallback<?> mHost; FragmentContainer mContainer; Fragment mParent; Fragment mPrimaryNav; boolean mNeedMenuInvalidate; boolean mStateSaved; boolean mDestroyed; String mNoTransactionsBecause; boolean mHavePendingDeferredStart; // Temporary vars for removing redundant operations in BackStackRecords: ArrayList<BackStackRecord> mTmpRecords; ArrayList<Boolean> mTmpIsPop; ArrayList<Fragment> mTmpAddedFragments; // Temporary vars for state save and restore. Bundle mStateBundle = null; SparseArray<Parcelable> mStateArray = null; // Postponed transactions. ArrayList<StartEnterTransitionListener> mPostponedTransactions; // Prior to O, we allowed executing transactions during fragment manager state changes. // This is dangerous, but we want to keep from breaking old applications. boolean mAllowOldReentrantBehavior; // Saved FragmentManagerNonConfig during saveAllState() and cleared in noteStateNotSaved() FragmentManagerNonConfig mSavedNonConfig;
我们可以看到,里面有各种状态位保存,回退栈等,都在这个类里面记录。
到这里我们应该知道Fragment体系的几个类是干嘛的了。接下从一个方法来看看Fragment的事务如何处理。
我们一般使用Fragment是按照下面这样使用的,开启一个事务,最后commit
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction(); transaction.replace(R.id.main_fragment_container, homeFragment); transaction.commit();
我们来看下beginTransaction方法的实现
@Override public FragmentTransaction beginTransaction() { return new BackStackRecord(this); }
可以见到,其返回了一个BackStackRecord类,那么这个类是继承于FragmentTransaction的
/** * @hide Entry of an operation on the fragment back stack. */ final class BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry, FragmentManagerImpl.OpGenerator { static final String TAG = FragmentManagerImpl.TAG; final FragmentManagerImpl mManager; 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 class Op { int cmd; // 表明动作 Fragment fragment; //被操作的Fragment int enterAnim; // 进入动画 int exitAnim; // 退出动画 int popEnterAnim; // 弹入动画 int popExitAnim; // 弹出动画 Op() { } Op(int cmd, Fragment fragment) { this.cmd = cmd; this.fragment = fragment; } } ArrayList<Op> mOps = new ArrayList<>(); int mEnterAnim; int mExitAnim; int mPopEnterAnim; int mPopExitAnim; int mTransition; int mTransitionStyle; boolean mAddToBackStack; boolean mAllowAddToBackStack = true; String mName; boolean mCommitted; int mIndex = -1; boolean mReorderingAllowed; ArrayList<Runnable> mCommitRunnables; int mBreadCrumbTitleRes; CharSequence mBreadCrumbTitleText; int mBreadCrumbShortTitleRes; CharSequence mBreadCrumbShortTitleText; ArrayList<String> mSharedElementSourceNames; ArrayList<String> mSharedElementTargetNames;
我们从其add方法来看
public FragmentTransaction add(Fragment fragment, String tag) { doAddOp(0, fragment, tag, OP_ADD); return this; } private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) { if (mManager.getTargetSdk() > Build.VERSION_CODES.N_MR1) { final Class fragmentClass = fragment.getClass(); final 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."); } } fragment.mFragmentManager = mManager; if (tag != null) { .... fragment.mTag = tag; } if (containerViewId != 0) { ... fragment.mContainerId = fragment.mFragmentId = containerViewId; } addOp(new Op(opcmd, fragment)); } void addOp(Op op) { mOps.add(op); op.enterAnim = mEnterAnim; op.exitAnim = mExitAnim; op.popEnterAnim = mPopEnterAnim; op.popExitAnim = mPopExitAnim; }
可以看到,其将整个操作封装成了一个Op并将其添加到mOps列表里面去。这个列表是我们在上面定义的,一个链表。
这个流程到这其实就结束了,接下来我们会调用 commit方法。 commit里面调用FragmentManager的enqueueAction方法
public int commit() { return commitInternal(false); } int commitInternal(boolean allowStateLoss) { if (mCommitted) { throw new IllegalStateException("commit already called"); } if (FragmentManagerImpl.DEBUG) { Log.v(TAG, "Commit: " + this); LogWriter logw = new LogWriter(Log.VERBOSE, TAG); PrintWriter pw = new FastPrintWriter(logw, false, 1024); dump(" ", null, pw, null); pw.flush(); } mCommitted = true; if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this); } else { mIndex = -1; } mManager.enqueueAction(this, allowStateLoss); //调用FragmentManager的enqueueAction方法 return mIndex; }
FragmentManager中将操作添加进pendingAction中
/** * Adds an action to the queue of pending actions. * * @param action the action to add * @param allowStateLoss whether to allow loss of state information * @throws IllegalStateException if the activity has been destroyed */ public void enqueueAction(OpGenerator action, boolean allowStateLoss) { if (!allowStateLoss) { checkStateLoss(); // 这边会检查状态,若activity已经走了onSaveInstanceStatus,这边会抛出异常 } synchronized (this) { if (mDestroyed || mHost == null) { if (allowStateLoss) { // This FragmentManager isn't attached, so drop the entire transaction. return; } throw new IllegalStateException("Activity has been destroyed"); } if (mPendingActions == null) { mPendingActions = new ArrayList<>(); } // 将commit处理操作放置到mPendingActions列表中 mPendingActions.add(action); scheduleCommit(); } }
接下来开启执行的runnable,进行调度动作
Runnable mExecCommit = new Runnable() { @Override public void run() { execPendingActions(); } }; private void scheduleCommit() { synchronized (this) { boolean postponeReady = mPostponedTransactions != null && !mPostponedTransactions.isEmpty(); boolean pendingReady = mPendingActions != null && mPendingActions.size() == 1; if (postponeReady || pendingReady) { mHost.getHandler().removeCallbacks(mExecCommit); mHost.getHandler().post(mExecCommit); } } }
这样会调用到Runnable中的 execPendingActions()
方法
/** * Only call from main thread! */ public boolean execPendingActions() { ensureExecReady(true); boolean didSomething = false; // 进入死循环, generateOpsForPendingActions会判断当前是否还有任务 while (generateOpsForPendingActions(mTmpRecords, mTmpIsPop)) { mExecutingActions = true; try { // 去掉多余任务,并执行任务 // 执行任务的时候,会去挨个调用BackStackRecord中的expandOps方法。里面会执行之前的Ops removeRedundantOperationsAndExecute(mTmpRecords, mTmpIsPop); } finally { // 清理多余任务 cleanupExec(); } didSomething = true; } doPendingDeferredStart(); burpActive(); return didSomething; }
我们看一下 removeRedundantOperationsAndExecute里面调用BackStackRecord中的expandOps方法的逻辑,在这里就负责取出各个事务进行操作。
Fragment expandOps(ArrayList<Fragment> added, Fragment oldPrimaryNav) { //遍历链表挨个取出动作进行执行 for (int opNum = 0; opNum < mOps.size(); opNum++) { final Op op = mOps.get(opNum); switch (op.cmd) { case OP_ADD: case OP_ATTACH: added.add(op.fragment); break; case OP_REMOVE: case OP_DETACH: { added.remove(op.fragment); if (op.fragment == oldPrimaryNav) { mOps.add(opNum, new Op(OP_UNSET_PRIMARY_NAV, op.fragment)); opNum++; oldPrimaryNav = null; } } break; case OP_REPLACE: { final Fragment f = op.fragment; 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.enterAnim = op.enterAnim; removeOp.popEnterAnim = op.popEnterAnim; removeOp.exitAnim = op.exitAnim; removeOp.popExitAnim = op.popExitAnim; mOps.add(opNum, removeOp); added.remove(old); opNum++; } } } if (alreadyAdded) { mOps.remove(opNum); opNum--; } else { op.cmd = 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.fragment; } break; } } return oldPrimaryNav; }
对于Fragment的生命周期,很多人都理解不懂,毕竟生命周期过多,从源码看,应该会好很多。我们看下Activity是如何回调Fragment的生命周期的。
Activity源码中:
protected void onCreate(@Nullable Bundle savedInstanceState) { ... //调用FragmnentController的 dispatchCreate方法 mFragments.dispatchCreate(); } public void dispatchCreate() { mHost.mFragmentManager.dispatchCreate(); }
FragmentManager中
public void dispatchCreate() { mStateSaved = false; dispatchMoveToState(Fragment.CREATED); } private void dispatchMoveToState(int state) { if (mAllowOldReentrantBehavior) { moveToState(state, false); } else { try { mExecutingActions = true; moveToState(state, false); } finally { mExecutingActions = false; } } execPendingActions(); } 最后会调到: 这个方法特别长, static final int INVALID_STATE = -1; // Invalid state used as a null value. static final int INITIALIZING = 0; // Not yet created. static final int CREATED = 1; // Created. static final int ACTIVITY_CREATED = 2; // The activity has finished its creation. static final int STOPPED = 3; // Fully created, not started. static final int STARTED = 4; // Created and started, not resumed. static final int RESUMED = 5; // Created started and resumed. void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) { switch (f.mState) { case Fragment.INITIALIZING: //里面会回调onAttach ... f.onAttach(mHost.getContext()); break; case Fragment.CREATED: f.mView = f.performCreateView(f.performGetLayoutInflater( // 回调onCreateView f.mSavedFragmentState), container, f.mSavedFragmentState); f.onViewCreated(f.mView, f.mSavedFragmentState); // 回调onViewCreated f.performActivityCreated(f.mSavedFragmentState); // 回调 onActivityCreated(savedInstanceState); dispatchOnFragmentActivityCreated(f, f.mSavedFragmentState, false); if (f.mView != null) { f.restoreViewState(f.mSavedFragmentState); // 回调 onViewStateRestored(savedInstanceState); } case Fragment.ACTIVITY_CREATED: if (newState > Fragment.ACTIVITY_CREATED) { f.mState = Fragment.STOPPED; } // fall through case Fragment.STOPPED: if (newState > Fragment.STOPPED) { if (DEBUG) Log.v(TAG, "moveto STARTED: " + f); f.performStart(); // 回调 onStart dispatchOnFragmentStarted(f, false); } // fall through case Fragment.STARTED: if (newState > Fragment.STARTED) { if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f); f.performResume(); // 回调 onResume dispatchOnFragmentResumed(f, false); // Get rid of this in case we saved it and never needed it. f.mSavedFragmentState = null; f.mSavedViewState = null; } .... }
其他的生命周期也是类似的,大体都一样
final void performPause() { mDoReportFullyDrawn = false; mFragments.dispatchPause(); // 通知Fragment onPause mCalled = false; onPause(); //Activity自身onPause mResumed = false; if (!mCalled && getApplicationInfo().targetSdkVersion >= android.os.Build.VERSION_CODES.GINGERBREAD) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onPause()"); } mResumed = false; } final void performResume() { performRestart(); mFragments.execPendingActions(); mLastNonConfigurationInstances = null; mCalled = false; // mResumed is set by the instrumentation mInstrumentation.callActivityOnResume(this); // 调用Activity的onResume // Now really resume, and install the current status bar and menu. mCalled = false; mFragments.dispatchResume(); // 调用Fragment的onResume mFragments.execPendingActions(); onPostResume(); if (!mCalled) { throw new SuperNotCalledException( "Activity " + mComponent.toShortString() + " did not call through to super.onPostResume()"); } }
通过阅读这些源码,我们可以总结出Fragment的生命周期如下
到此,谢谢大家的阅读。
作者:Anderson大码渣,欢迎关注我的简书: Anderson大码渣