Android-Fragment源码解析

来源:互联网 发布:windows服务器监控 编辑:程序博客网 时间:2024/05/29 19:04
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();
关键方法流程图


核心方法介绍
当执行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);
    }
}
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 (DEBUGLog.v(TAG"moveto STARTED: " + f);
                    f.performStart();
                }
            case Fragment.STARTED:
                if (newState > Fragment.STARTED) {
                    if (DEBUGLog.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 (DEBUGLog.v(TAG"movefrom RESUMED: " + f);
                    f.performPause();
                }
            case Fragment.STARTED:
                if (newState < Fragment.STARTED) {
                    if (DEBUGLog.v(TAG"movefrom STARTED: " + f);
                    f.performStop();
                }
            case Fragment.STOPPED:
                if (newState < Fragment.STOPPED) {
                    if (DEBUGLog.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状态变迁图


参考
http://www.jianshu.com/p/180d2cc0feb5