Android-Fragment源码解析
UML类图
主要类含义介绍
FragmentController
FragmentController为Fragment的宿主提供一个控制器,对Fragment生命周期操作,提供一个控制流程。FragmentController中持有FragmentHostCallback对象,对于Fragment生命周期的操作,主要是通过FragmentHostCallback来实现的。而FragmentHostCallback中的操作,则主要通过FragmentManagerImpl来实现。
FragmentContainer
Fragment容器的回调接口
FragmentHostCallback
Fragment宿主的回调接口,要使一个对象具有持有和管理fragment生命周期的能力,我们只需要实现FragmentHostCallback中的函数。当我们对Fragment进行操作的时候,就会对调用FragmentController的操作,从而间接的调用FragmentHostCallback对象。在FragmentHostCallback中,暴露出了对Fragment操作的一些接口,通过重写这些接口,可以将Fragment操作与Fragment宿主(例如FragmentActivity)捆绑起来。
FragmentActivity
系统为我们提供的,将Activity作为Fragment的宿主的实现类。
FragmentActivity.HostCallbacks
FragmentActivity.HostCallbacks继承FragmentHostCallback,通过重写FragmentHostCallback中的函数,将将Fragment操作与Fragment宿主(例如FragmentActivity)捆绑起来。有些方法需要通过宿主来实现,单单依靠Fragment,无法实现。
FragmentManager
FragmentManager,顾名思义,就是Fragment的真正管理类,主要提供了对Fragment进行操作。实际开发中,对Fragment进行操作的方法,例如beginTransaction(),popBackStack()都是通过该类来获取的。需要注意的是,FragmentManager为一个抽象类,真正的实现类为FragmentManagerImpl
FragmentManager.BackStackEntry
FragmentManager进行pop栈的操作接口,实现类为BackStackRecord,每个Fragment事务FragmentTrasaction都为BackStackRecord
FragmentManagerImpl
Fragmentmanageriml为FragmentManager的实现类,实现了Fragment所有的管理操作,为Fragment操作的入口方法,起到管理Fragment的作用。
FragmentManagerState
FragmentManagerState实现了Parcelable序列化接口,主要用于FragmentManager状态保存。当Activity内存不足被销毁时,保存FragmentManager的当前状态,等到再次启动Activity时,恢复FragmentManager中的Fragment对象。其中,包含了Fragment.FragmentState数组和BackStatckRecord.BackStackState数组,分别保存Fragment的状态信息和Fragment事务(BackStatckRecord)的状态信息。
Fragment.FragmentState
Fragment.FragmentState实现了Parcelable序列化接口,主要用于Fragment状态保存。当Activity内存不足被销毁时,保存Fragment的当前状态,等到再次启动Activity时,恢复Fragment对象。值得一提的是,FragmentState恢复Fragment对象的时候,通过反射调用Fragment参数为空的构造函数,来恢复Fragment对象。这就是为什么Fragment不应该使用有参构造函数的原因。
Fragment
Fragment = View + 固有属性 + State
View,就是添加到界面中的视图;固有属性,就是Attr指得是Fragment的一些固有属性,不会随着Fragment的生命周期发生变化;State,就是Fragemnt当前的状态,Fragment在生命周期变迁中中会发生改变的状态。其实说白了,Fragment就是一个拥有生命周期的自定义View。
FragmentTransaction
Fragment操作的事务,每个FragmentTransaction对象,代表着系列Fragment操作的事务。操作Fragment的添加,删除,隐藏,显示时,都要使用FragmentTransaction。FragmentTransaction其实是个抽象类,真正的实现类为BackStackRecord。
BackStackRecord
BackStackRecord实现了FragmentTransaction,每一个BackStackRecord对象,都代表了一次Fragment操作事务。每次对Fragment进行提交操作,都会生产一个BackStackRecord对象。然后,将对Fragment的每一步操作都封装成Op对象,以链表的形式添加到BackStackRecord中去。BackStackRecord实现了BackStatckRecord.BackStackState接口,表示BackStackRecord可以被FragmentManager保存到操作堆栈中,到执行popBackStack()时,可以恢复原先的BackStackRecord事务。BackStackRecord实现了Runnable接口,当执行FragmentTransaction.commit()方法时,会将BackStackRecord对象当做Runnable,添加到Handler处理队列中,调用BackStackRecord.run()方法来执行上述操作链表中的Op对象集。
Op
Op对象,主要保存了FragmentTransaction操作事务中的单次操作,是相对于Fragment而言的。每个Op对象,保存了操作的Fragment对象,切换动画等对象。Op操作是以链表形式保存起来的。
关键流程分析
以Fragment.replace()为例子,进行Fragment的关键流程分析。执行代码如下:
Fragment fragment = DrawerFragment.instance();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.test_content, fragment);
transaction.commit();
FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction transaction = fragmentManager.beginTransaction();
transaction.add(R.id.test_content, fragment);
transaction.commit();
关键方法流程图
核心方法介绍
当执行BackStackRecord.commit()的时候,会将BackStackRecord作为Runnable对象,保存到FragmentManagerImpl中。最终,会在Handler中,执行BackStackRecord.run()方法。所以,真正的Fragment操作,都是在run()方法中进行的。
public void run() {
...
Op op = mHead;
while (op != null) {
int enterAnim = state != null ? 0 : op.enterAnim;
int exitAnim = state != null ? 0 : op.exitAnim;
switch (op.cmd) {
case OP_ADD: {
Fragment f = op.fragment;
f.mNextAnim = enterAnim;
mManager.addFragment(f, false);
} break;
case OP_REPLACE: {
...
} break;
case OP_REMOVE: {
Fragment f = op.fragment;
f.mNextAnim = exitAnim;
mManager.removeFragment(f, transition, transitionStyle);
} break;
case OP_HIDE: {
...
} break;
...
//更多case
}
op = op.next;
}
//将active状态的fragment全部执行状态变迁检查
mManager.moveToState(mManager.mCurState, transition, transitionStyle, true);
if (mAddToBackStack) {
mManager.addBackStackState(this);
}
}
...
Op op = mHead;
while (op != null) {
int enterAnim = state != null ? 0 : op.enterAnim;
int exitAnim = state != null ? 0 : op.exitAnim;
switch (op.cmd) {
case OP_ADD: {
Fragment f = op.fragment;
f.mNextAnim = enterAnim;
mManager.addFragment(f, false);
} break;
case OP_REPLACE: {
...
} break;
case OP_REMOVE: {
Fragment f = op.fragment;
f.mNextAnim = exitAnim;
mManager.removeFragment(f, transition, transitionStyle);
} break;
case OP_HIDE: {
...
} break;
...
//更多case
}
op = op.next;
}
//将active状态的fragment全部执行状态变迁检查
mManager.moveToState(mManager.mCurState, transition, transitionStyle, true);
if (mAddToBackStack) {
mManager.addBackStackState(this);
}
}
run()方法内部根据不同的cmd走了很不不同的分支,每个分支内部都会对,fragment状态做改变,最后调用moveToState将fragment的生命周期状态mState进行变迁,下面是moveToState()方法。
void moveToState(Fragment f, int newState, int transit, int transitionStyle, boolean keepActive) {
// Fragments that are not currently added will sit in the onCreate() state.
...
if (f.mState < newState) {
// For fragments that are created from a layout, when restoring from
// state we don't want to allow them to be created until they are
// being reloaded from the layout.
...
switch (f.mState) {
case Fragment.INITIALIZING:
...
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
...
}
case Fragment.ACTIVITY_CREATED:
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
f.performStart();
}
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
f.performResume();
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);
f.performPause();
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
f.performStop();
}
case Fragment.STOPPED:
if (newState < Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
f.performReallyStop();
}
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
...
}
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
...
}
}
}
...
}
// Fragments that are not currently added will sit in the onCreate() state.
...
if (f.mState < newState) {
// For fragments that are created from a layout, when restoring from
// state we don't want to allow them to be created until they are
// being reloaded from the layout.
...
switch (f.mState) {
case Fragment.INITIALIZING:
...
case Fragment.CREATED:
if (newState > Fragment.CREATED) {
...
}
case Fragment.ACTIVITY_CREATED:
case Fragment.STOPPED:
if (newState > Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);
f.performStart();
}
case Fragment.STARTED:
if (newState > Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);
f.performResume();
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);
f.performPause();
}
case Fragment.STARTED:
if (newState < Fragment.STARTED) {
if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);
f.performStop();
}
case Fragment.STOPPED:
if (newState < Fragment.STOPPED) {
if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);
f.performReallyStop();
}
case Fragment.ACTIVITY_CREATED:
if (newState < Fragment.ACTIVITY_CREATED) {
...
}
case Fragment.CREATED:
if (newState < Fragment.CREATED) {
...
}
}
}
...
}
Fragment状态变迁发生在用户主动发起transaction,或者fragment被add到activity之后跟随activity的生命周期变化一起发生改变。每次状态变迁最终都会走到函数moveToState,字面意思是将fragment迁移到新的状态。fragment的state取值,为前面提到的七中状态,其中最低值是INITIALIZING状态,代表fragment刚创建,还未被add,
最高状态值是RESUMED,代表fragment处于前台。 所以moveToState内部分两条线,状态跃升,和状态降低,里面各有一个switch判断,注意到switch里每个case都没有break,这意味着,状态可以持续变迁,比如从INITIALIZING,一直跃升到RESUMED,将每个case都走一遍,每次case语句内,都会改变state的值。
Fragment状态变迁图