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();
关键方法流程图


核心方法介绍
当执行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状态变迁图


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值