Fragment的生命周期我们都不陌生,但是其如何利用FragmentManager从Activity生命周期挂载而来的呢,尤其是看了glide源码后,发现其巧妙的利用了FragmentManager来绑定自己的生命周期,那么为了更清晰的深入理解,一起来看下6.0的源码是如何处理的。
FragmentActivity
- 1.从启动一个FragmentActivity开始。从onCreate()方法中
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
@SuppressWarnings("deprecation")
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
mFragments.attachHost(null /*parent*/);
super.onCreate(savedInstanceState);
NonConfigurationInstances nc =
(NonConfigurationInstances) getLastNonConfigurationInstance();
if (nc != null) {
mFragments.restoreLoaderNonConfig(nc.loaders);
}
if (savedInstanceState != null) {
Parcelable p = savedInstanceState.getParcelable(FRAGMENTS_TAG);
mFragments.restoreAllState(p, nc != null ? nc.fragments : null);
}
mFragments.dispatchCreate();
}
- 1.1 重点关注一下 mFragments 的操作。当前的mFragments其实是FragmentController,而FragmentHostCallback在FragmentController初始化时进行初始化,在FragmentHostCallback中可以拿到FragmentManager的子类FragmentManagerImpl。继续看FragmentController的代码
//FragmentController初始化CallBack
public static final FragmentController createController(FragmentHostCallback<?> callbacks) {
return new FragmentController(callbacks);
}
private FragmentController(FragmentHostCallback<?> callbacks) {
mHost = callbacks;
}
public void attachHost(Fragment parent) {
mHost.mFragmentManager.attachController(
mHost, mHost /*container*/, parent);
}
public void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) {
mHost.mFragmentManager.restoreAllState(state, nonConfig);
}
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
- 1.2当前的操作其实都是对FragmentManager进行操作,继续看FragmentManagerImpl代码
// 初始化赋值操作
public void attachController(FragmentHostCallback host,
FragmentContainer container, Fragment parent) {
if (mHost != null) throw new IllegalStateException("Already attached");
mHost = host;
mContainer = container;
mParent = parent;
}
void restoreAllState(Parcelable state, FragmentManagerNonConfig nonConfig) {
......
if (nonConfig != null) {
List<Fragment> nonConfigFragments = nonConfig.getFragments();
childNonConfigs = nonConfig.getChildNonConfigs();
final int count = nonConfigFragments != null ? nonConfigFragments.size() : 0;
for (int i = 0; i < count; i++) {
Fragment f = nonConfigFragments.get(i);
if (DEBUG) Log.v(TAG, "restoreAllState: re-attaching retained " + f);
FragmentState fs = fms.mActive[f.mIndex];
fs.mInstance = f;
f.mSavedViewState = null;
f.mBackStackNesting = 0;
f.mInLayout = false;
f.mAdded = false;
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;
}
}
}
// Build the full list of active fragments, instantiating them from
// their saved state.
mActive = new ArrayList<>(fms.mActive.length);
// 注意,后面会用到
...
}
public void dispatchCreate() {
mStateSaved = false;
mExecutingActions = true;
moveToState(Fragment.CREATED, false);
mExecutingActions = false;
}
- 1.3 以上,attachController() 只是简单的初始化的赋值操作,并无对生命周期相关的,继续看restoreAllState(),同样的初始化的重置操作,这里
mActive = new ArrayList(fms.mActive.length)初始化了一个空的mActive的list。继续看dispatchCreate(),其中moveToState
void moveToState(int newState, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No activity");
}
if (!always && newState == mCurState) {
return;
}
mCurState = newState;
if (mActive != null) {
boolean loadersRunning = false;
// Must add them in the proper order. mActive fragments may be out of order
if (mAdded != null) {
final int numAdded = mAdded.size();
for (int i = 0; i < numAdded; i++) {
Fragment f = mAdded.get(i);
moveFragmentToExpectedState(f);
if (f.mLoaderManager != null) {
loadersRunning |= f.mLoaderManager.hasRunningLoaders();
}
}
}
// Now iterate through all active fragments. These will include those that are removed
// and detached.
final int numActive = mActive.size();
for (int i = 0; i < numActive; i++) {
Fragment f = mActive.get(i);
if (f != null && (f.mRemoving || f.mDetached) && !f.mIsNewlyAdded) {
moveFragmentToExpectedState(f);
if (f.mLoaderManager != null) {
loadersRunning |= f.mLoaderManager.hasRunningLoaders();
}
}
}
if (!loadersRunning) {
startPendingDeferredFragments();
}
if (mNeedMenuInvalidate && mHost != null && mCurState == Fragment.RESUMED) {
mHost.onSupportInvalidateOptionsMenu();
mNeedMenuInvalidate = false;
}
}
}
1.4 moveToState() 其实是更新FragmentManager的状态至Fragment,但是当前并无Fragment,mActive在restoreAllState()初始化出来后只是个空的list,因此并没有实质的操作。至此FragmentActivity onCreate()都是初始化的操作。
2 Fragment的真正启动是当我们调用FragmentManager.beginTransaction().add(fragmet).commit()时触发。看下代码
public abstract class FragmentTransaction {
......
public abstract int commit();
/**
* Calls {@link #add(int, Fragment, String)} with a 0 containerViewId.
*/
public abstract FragmentTransaction add(Fragment fragment, String tag);
/**
* Calls {@link #add(int, Fragment, String)} with a null tag.
*/
public abstract FragmentTransaction add(@IdRes int containerViewId, Fragment fragment);
public abstract FragmentTransaction add(@IdRes int containerViewId, Fragment fragment,
@Nullable String tag);
......
}
- 2.1 抽象类FragmentTransaction,这里有个add(Fragment fragment, String tag)方法,添加一个Fragment,只设置tag,不设置viewId,说白了添加一个不妨碍业务的空Fragment方法,这是glide的绑定生命周期的一个点。继续看实现类
final class BackStackRecord extends FragmentTransaction implements
FragmentManager.BackStackEntry, Runnable {
...
public FragmentTransaction add(int containerViewId, Fragment fragment) {
doAddOp(containerViewId, fragment, null, OP_ADD);
return this;
}
private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {
fragment.mFragmentManager = mManager;
if