==本文所引用的代码均为support-v4-23.0.1包中的源码,使用‘…’表示省略部分代码。==
当在Activity的onCreate方法中通过一下方式添加Fragment,运行程序,便可以修饰在屏幕上。
FragmentManager fm = getSupportFragmentManager();
FragmentTransaction transaction = fm.beginTransaction();
transaction.add(resId, fragmentA);
transaction.commit();
这几行代码让Fragment经历了怎样的一番旅途,最终被关联到宿主Activity并显示。我准备扒一扒support-v4-23.0.0的源码,探索这一段神奇的旅途。
一 相关的类
与此相关的类主要有10个,分别为:
FragmentManger为抽象类,定义对Fragment的操作行为,子类为FragmentMangerImpl。FragmentMangerImpl又实现了LayoutInflaterFactory接口,是真正对Fragment执行初始化,显示和移除等等操作的类。
FragmentTransaction为抽象类,定义对Fragment操作事务行为,子类为BackStackRecord。BackStackRecord又实现了Runnable和FragmentManger.BackStackEntry接口,是执行Fragment添加,显示,隐藏和移除等等事务的类。Op为BackStackRecord的静态内部类,当使用FragmentTransaction添加,替换,隐藏,移除等等操作便会在BackStackRecord对象中生成一个记录操作行为和Fragment的Op对象,该对象以链表的方式存储在BackStackRecord中。
FragmentHostCallback为抽象类,又继承了FragmentContainer,子类为FragmentActivity的内部类HostCallback。
FragmentController封装对FragmentMangerImpl和HostCallback获取和操作的方法。
FragmentActivity用作Fragment的容器。
类图(Fragment的全家福):
流程分析
一,获取FragmentManager
在我们自定义的Activity中经常使用使用getSupportFragmentManager方法获取当前的FragmentManager(即FragmentMagagerImpl对象),那就先看看FragmentActivity类中的代码:
public FragmentManager getSupportFragmentManager() {
return mFragments.getSupportFragmentManager();
}
mFragments是什么类型,何时初始化与赋值?接着往FragmentActivity中查看:
//在对象创建是便已赋值
final FragmentController mFragments = FragmentController.createController(new HostCallbacks());
创建HostCallbacks对象,那就看看它的构造方法代码:
public HostCallbacks() {
//调用父类FragmentHostCallback的构造方法进行初始化
super(FragmentActivity.this /*fragmentActivity*/);
}
接着继续看FragmentHostCallback代码:
public abstract class FragmentHostCallback<E> extends FragmentContainer {
//当前关联的FragmentActivity对象
private final Activity mActivity;
//当前关联的Context对象,其实就是FragmentActivity对象
final Context mContext;
//当前FragmentActivity的mHandler属性
private final Handler mHandler;
final int mWindowAnimations;
//FragmentActivity获取的FragmentManager就是这个属性
final FragmentManagerImpl mFragmentManager = new FragmentManagerImpl();
//当前key为who,value为加载器LoaderManagerImpl
private SimpleArrayMap<String, LoaderManager> mAllLoaderManagers;
//
private LoaderManagerImpl mLoaderManager;
private boolean mCheckedForLoaderManager;
private boolean mLoadersStarted;
public FragmentHostCallback(Context context, Handler handler, int windowAnimations) {
this(null /*activity*/, context, handler, windowAnimations);
}
//FragmentActivity的内部类HostCallbacks调用赋值的构造方法
FragmentHostCallback(FragmentActivity activity) {
//使用activity给mContext赋值,activity.mHandler给mHandler赋值
this(activity, activity /*context*/, activity.mHandler, 0 /*windowAnimations*/);
}
//执行赋值
FragmentHostCallback(Activity activity, Context context, Handler handler, int windowAnimations) {
Activity = activity;
mContext = context;
mHandler = handler;
mWindowAnimations = windowAnimations;
}
...
}
再往回看看FragmentActivity的onCreate方法:
protected void onCreate(@Nullable Bundle savedInstanceState) {
//**这一步很重要**
//将FragmentController的mHost赋值给HostCallBack的mFragmentManager,便完成了当前Activity与FramgmentManger关联。
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);
}
//通知mFragmentManager当前Activity执行了onCreate
mFragments.dispatchCreate();
}
FragmentController中attachHost和dispatchCreate方法代码:
public void attachHost(Fragment parent) {
mHost.mFragmentManager.attachController(mHost, mHost /*container*/, parent);
}
public void dispatchCreate() {
mHost.mFragmentManager.dispatchCreate();
}
调用FragmentManagerImpl相关方法和属性的代码:
public void attachController(FragmentHostCallback host, FragmentContainer container, Fragment parent) {
if (mHost != null) throw new IllegalStateException("Already attached");
//将FragmentController中的mHost赋值给FragmentManagerImpl的mHost,自此便完成当前Activity与FramgmentManger关联
mHost = host;
mContainer = container;
mParent = parent;
}
//FragmentManagerImpl当前状态值,默认为初始化
int mCurState = Fragment.INITIALIZING;
public void dispatchCreate() {
mStateSaved = false;
//更新当前状态mCurState为Fragment.CREATED
moveToState(Fragment.CREATED, false);
}
void moveToState(int newState, boolean always) {
moveToState(newState, 0, 0, always);
}
void moveToState(int newState, int transit, int transitStyle, boolean always) {
if (mHost == null && newState != Fragment.INITIALIZING) {
throw new IllegalStateException("No host");
}
if (!always && mCurState == newState) {
return;
}
//更新当前状态mCurState为Fragment.CREATED
mCurState = newState;
//当从FragmentActivity的onCreate执行到此时,由于还未有添加Fragment,则mActive为null,便返回。
//执行完这些代码后,FragmentManagerImpl的mCurState为Fragment.CREATED
if (mActive != null) {
boolean loadersRunning = false;
for (int i=0; i<mActive.size(); i++) {
Fragment f = mActive.get(i);
if (f != null) {
moveToState(f, newState, transit, transitStyle, false);
...
}
}
...
}
}
当Activity的onCreate方法执行完super.onCreate(),我们便能够通过getSupportFragmentManager方法获取到一个可以正常使用的FragmentManagerImpl对象。
二,获取FragmentTransaction
调用FragmentManager的beginTransaction()方法获取FragmentTransaction。看看代码,究竟执行了哪些操作。