首页 > 代码库 > 详解fragment(一):从源代码看fragment的生命周期

详解fragment(一):从源代码看fragment的生命周期

前面讲了那么多xml,我们缓一下,现在讲从代码角度来看fragment的创建。

我们通常会在FragmentActivity中通过如下方法:

getSupportFragmentManager().beginTransaction().replace(R.id.content, fragment, tag).commit();
getSupportFragmentManager().beginTransaction().add(R.id.content, fragment, tag).commit();
来调用新建或者取代一个fragment。那你知道这中间发生了什么事情吗,别急,让我们慢慢看代码。

FragmentActivity.java中有个方法:getSupportFragmentManager

public FragmentManager getSupportFragmentManager() {
        return mFragments;
    }
这个方法用于获取一个FragmentManager,那么这个mFragments是哪里来的呢,我们搜一下这个类,不难发现他的初始化是这个样子的:

    final FragmentManagerImpl mFragments = new FragmentManagerImpl();
从中我们就可以知道FragmentManager以及FragmentManagerImpl是父子类关系。

在FragmentManagerImpl.java中:

final class FragmentManagerImpl extends FragmentManager
而且不用说也可以看出来,FragmentManagerImpl是FragmentManager的具体实现,然后自然而然的我们能找到代码:

public FragmentTransaction beginTransaction()
  {
    return new BackStackRecord(this);
  }

自然而然的我们要去找到BackStackRecord.java这个类了,代码如下:

public BackStackRecord(FragmentManagerImpl manager) {
        mManager = manager;
    }

接下来,我们看如何添加一个Fragment到Activity,无非是addFragment方法了,我们到FragmentTransaction中看一下(前面说过的Impl类是具体实现):

public void addFragment(Fragment paramFragment, boolean paramBoolean)
  {
    if (this.mAdded == null)
      this.mAdded = new ArrayList();
    if (DEBUG)
      Log.v("FragmentManager", "add: " + paramFragment);
    makeActive(paramFragment);
    if (!paramFragment.mDetached)
    {
      this.mAdded.add(paramFragment);
      paramFragment.mAdded = true;
      paramFragment.mRemoving = false;
      if ((paramFragment.mHasMenu) && (paramFragment.mMenuVisible))
        this.mNeedMenuInvalidate = true;
      if (paramBoolean)
        moveToState(paramFragment);
    }
  }
这里果然是有一个数组ArrayList在管理,ArrayList是啥?是动态数组,这就意味着他是可以动态添加的,不是栈,所以里面的Fragments可以随便获取以及插入。

其中最重要的那句话就是moveToState,其实现代码还是比较多的,我们贴一下看看:

void moveToState(Fragment paramFragment, int paramInt1, int paramInt2, int paramInt3)
  {
    if ((!paramFragment.mAdded) && (paramInt1 > 1))
      paramInt1 = 1;
    if ((paramFragment.mRemoving) && (paramInt1 > paramFragment.mState))
      paramInt1 = paramFragment.mState;
    if (paramFragment.mState < paramInt1)
    {
      if ((paramFragment.mFromLayout) && (!paramFragment.mInLayout))
        return;
      if (paramFragment.mAnimatingAway != null)
      {
        paramFragment.mAnimatingAway = null;
        moveToState(paramFragment, paramFragment.mStateAfterAnimating, 0, 0);
      }
      switch (paramFragment.mState)
      {
      default:
      case 0:
      case 1:
      case 2:
      case 3:
      case 4:
      }
    }
    while (true)
    {
      paramFragment.mState = paramInt1;
      break;
      if (DEBUG)
        Log.v("FragmentManager", "moveto CREATED: " + paramFragment);
      if (paramFragment.mSavedFragmentState != null)
      {
        paramFragment.mSavedViewState = paramFragment.mSavedFragmentState.getSparseParcelableArray("android:view_state");
        paramFragment.mTarget = getFragment(paramFragment.mSavedFragmentState, "android:target_state");
        if (paramFragment.mTarget != null)
          paramFragment.mTargetRequestCode = paramFragment.mSavedFragmentState.getInt("android:target_req_state", 0);
      }
      paramFragment.mActivity = this.mActivity;
      paramFragment.mFragmentManager = this.mActivity.mFragments;
      paramFragment.mCalled = false;
      paramFragment.onAttach(this.mActivity);
      if (!paramFragment.mCalled)
        throw new SuperNotCalledException("Fragment " + paramFragment + " did not call through to super.onAttach()");
        //第一步:attach
      this.mActivity.onAttachFragment(paramFragment);
      if (!paramFragment.mRetaining)
      {
        paramFragment.mCalled = false;
        //第二步:onCreate
        paramFragment.onCreate(paramFragment.mSavedFragmentState);
        if (!paramFragment.mCalled)
          throw new SuperNotCalledException("Fragment " + paramFragment + " did not call through to super.onCreate()");
      }
      paramFragment.mRetaining = false;
      if (paramFragment.mFromLayout)
      {
      //第三步:onCreateView
        paramFragment.mView = paramFragment.onCreateView(paramFragment.getLayoutInflater(paramFragment.mSavedFragmentState), null, paramFragment.mSavedFragmentState);
        if (paramFragment.mView == null)
          break label570;
        paramFragment.mInnerView = paramFragment.mView;
        paramFragment.mView = NoSaveStateFrameLayout.wrap(paramFragment.mView);
        if (paramFragment.mHidden)
          paramFragment.mView.setVisibility(8);
        paramFragment.onViewCreated(paramFragment.mView, paramFragment.mSavedFragmentState);
      }
      while (true)
      {
        if (paramInt1 <= 1)
          break label777;
        if (DEBUG)
          Log.v("FragmentManager", "moveto ACTIVITY_CREATED: " + paramFragment);
        if (paramFragment.mFromLayout)
          break;
        ViewGroup localViewGroup = null;
        if (paramFragment.mContainerId != 0)
        {
          localViewGroup = (ViewGroup)this.mActivity.findViewById(paramFragment.mContainerId);
          if ((localViewGroup == null) && (!paramFragment.mRestored))
          {
            throw new IllegalArgumentException("No view found for id 0x" + Integer.toHexString(paramFragment.mContainerId) + " for fragment " + paramFragment);
            label570: paramFragment.mInnerView = null;
            continue;
          }
        }
        paramFragment.mContainer = localViewGroup;
        paramFragment.mView = paramFragment.onCreateView(paramFragment.getLayoutInflater(paramFragment.mSavedFragmentState), localViewGroup, paramFragment.mSavedFragmentState);
        if (paramFragment.mView == null)
          break label753;
        paramFragment.mInnerView = paramFragment.mView;
        paramFragment.mView = NoSaveStateFrameLayout.wrap(paramFragment.mView);
        if (localViewGroup != null)
        {
          Animation localAnimation2 = loadAnimation(paramFragment, paramInt2, true, paramInt3);
          if (localAnimation2 != null)
            paramFragment.mView.startAnimation(localAnimation2);
          localViewGroup.addView(paramFragment.mView);
        }
        if (paramFragment.mHidden)
          paramFragment.mView.setVisibility(8);
        paramFragment.onViewCreated(paramFragment.mView, paramFragment.mSavedFragmentState);
      }
      while (true)
      {
        paramFragment.mCalled = false;
        //第四步:onActivityCreated
        paramFragment.onActivityCreated(paramFragment.mSavedFragmentState);
        if (paramFragment.mCalled)
          break;
        throw new SuperNotCalledException("Fragment " + paramFragment + " did not call through to super.onActivityCreated()");
        label753: paramFragment.mInnerView = null;
      }
      if (paramFragment.mView != null)
        paramFragment.restoreViewState();
      paramFragment.mSavedFragmentState = null;
      label777: if (paramInt1 > 3)
      {
        if (DEBUG)
          Log.v("FragmentManager", "moveto STARTED: " + paramFragment);
        paramFragment.mCalled = false;
        paramFragment.performStart();
        if (!paramFragment.mCalled)
          throw new SuperNotCalledException("Fragment " + paramFragment + " did not call through to super.onStart()");
      }
      if (paramInt1 <= 4)
        continue;
      if (DEBUG)
        Log.v("FragmentManager", "moveto RESUMED: " + paramFragment);
      paramFragment.mCalled = false;
      paramFragment.mResumed = true;
      //第五步:onResume
      paramFragment.onResume();
      if (!paramFragment.mCalled)
        throw new SuperNotCalledException("Fragment " + paramFragment + " did not call through to super.onResume()");
      paramFragment.mSavedFragmentState = null;
      paramFragment.mSavedViewState = null;
      continue;
      if (paramFragment.mState <= paramInt1)
        continue;
      switch (paramFragment.mState)
      {
      default:
        break;
      case 1:
      case 5:
      case 4:
      case 3:
      case 2:
        while (paramInt1 < 1)
        {
          if ((this.mDestroyed) && (paramFragment.mAnimatingAway != null))
          {
            View localView = paramFragment.mAnimatingAway;
            paramFragment.mAnimatingAway = null;
            localView.clearAnimation();
          }
          if (paramFragment.mAnimatingAway == null)
            break label1519;
          paramFragment.mStateAfterAnimating = paramInt1;
          paramInt1 = 1;
          break;
          if (paramInt1 < 5)
          {
            if (DEBUG)
              Log.v("FragmentManager", "movefrom RESUMED: " + paramFragment);
            paramFragment.mCalled = false;
            //第六步:onPause
            paramFragment.onPause();
            if (!paramFragment.mCalled)
              throw new SuperNotCalledException("Fragment " + paramFragment + " did not call through to super.onPause()");
            paramFragment.mResumed = false;
          }
          if (paramInt1 < 4)
          {
            if (DEBUG)
              Log.v("FragmentManager", "movefrom STARTED: " + paramFragment);
            paramFragment.mCalled = false;
            paramFragment.performStop();
            if (!paramFragment.mCalled)
              throw new SuperNotCalledException("Fragment " + paramFragment + " did not call through to super.onStop()");
          }
          if (paramInt1 < 3)
          {
            if (DEBUG)
              Log.v("FragmentManager", "movefrom STOPPED: " + paramFragment);
            paramFragment.performReallyStop();
          }
          if (paramInt1 >= 2)
            continue;
          if (DEBUG)
            Log.v("FragmentManager", "movefrom ACTIVITY_CREATED: " + paramFragment);
          if ((paramFragment.mView != null) && (!this.mActivity.isFinishing()) && (paramFragment.mSavedViewState == null))
            saveFragmentViewState(paramFragment);
          paramFragment.mCalled = false;
          paramFragment.performDestroyView();
          if (!paramFragment.mCalled)
            throw new SuperNotCalledException("Fragment " + paramFragment + " did not call through to super.onDestroyView()");
          if ((paramFragment.mView != null) && (paramFragment.mContainer != null))
          {
            Animation localAnimation1 = null;
            if ((this.mCurState > 0) && (!this.mDestroyed))
              localAnimation1 = loadAnimation(paramFragment, paramInt2, false, paramInt3);
            if (localAnimation1 != null)
            {
              paramFragment.mAnimatingAway = paramFragment.mView;
              paramFragment.mStateAfterAnimating = paramInt1;
              localAnimation1.setAnimationListener(new Animation.AnimationListener(paramFragment)
              {
                public void onAnimationEnd(Animation paramAnimation)
                {
                  if (this.val$fragment.mAnimatingAway != null)
                  {
                    this.val$fragment.mAnimatingAway = null;
                    FragmentManagerImpl.this.moveToState(this.val$fragment, this.val$fragment.mStateAfterAnimating, 0, 0);
                  }
                }

                public void onAnimationRepeat(Animation paramAnimation)
                {
                }

                public void onAnimationStart(Animation paramAnimation)
                {
                }
              });
              paramFragment.mView.startAnimation(localAnimation1);
            }
            paramFragment.mContainer.removeView(paramFragment.mView);
          }
          paramFragment.mContainer = null;
          paramFragment.mView = null;
          paramFragment.mInnerView = null;
        }
        label1519: if (DEBUG)
          Log.v("FragmentManager", "movefrom CREATED: " + paramFragment);
        if (!paramFragment.mRetaining)
        {
          paramFragment.mCalled = false;
          //第八步:onDestroy
          paramFragment.onDestroy();
          if (!paramFragment.mCalled)
            throw new SuperNotCalledException("Fragment " + paramFragment + " did not call through to super.onDestroy()");
        }
        paramFragment.mCalled = false;
        //第九步:onDetach
        paramFragment.onDetach();
        if (!paramFragment.mCalled)
          throw new SuperNotCalledException("Fragment " + paramFragment + " did not call through to super.onDetach()");
        if (!paramFragment.mRetaining)
        {
          makeInactive(paramFragment);
          continue;
        }
        paramFragment.mActivity = null;
        paramFragment.mFragmentManager = null;
      }
    }
  }

本来不想贴这部分的代码的,但确实这个比较重要,还是看一下吧。

最后一步肯定是commit了,这个方法是由FragmentTransaction.java类调用的,其实包括前面的addFragment等都是在这个类调用的,可是他是个抽象类,具体的实现还是在Impl类中。我们还是稍微浏览一下这个类吧(只截取了部分):

public abstract class FragmentTransaction {

    public abstract FragmentTransaction add(int containerViewId, Fragment fragment);
   
    public abstract FragmentTransaction add(int containerViewId, Fragment fragment, String tag);
   
    public abstract FragmentTransaction replace(int containerViewId, Fragment fragment);
   
    public abstract FragmentTransaction replace(int containerViewId, Fragment fragment, String tag);
   
    public abstract FragmentTransaction remove(Fragment fragment);
   
    public abstract FragmentTransaction hide(Fragment fragment);
    
    
    public abstract FragmentTransaction show(Fragment fragment);

    
    public abstract FragmentTransaction detach(Fragment fragment);

    public abstract FragmentTransaction attach(Fragment fragment);

    public abstract int commit();
}

最后看commit的实现,本人目前还没找到,求告诉!