Fragment加载过程分析

Fragment加载到屏幕上的代码非常简单。getFragmentManager().beginTransaction().add(int addId,Fragment addFragment,String tag).commit();但是具体过程我们来看一下:

首先看getFragmentMananger()方法:它定义在Activity中:

[java]  view plain copy
  1. public FragmentManager getFragmentManager() {  
  2.         return mFragments;  
  3.     }  

它只是直接返回了成员变量mFragments。这个变量的类型是FragmentManagerImpl.它是FragmentManager的子类。与FragmentManager和FragmentManagerState处于同一个文件中。而FragmentManager实际上是一个抽象类。

接着看第二个。beginTransaction():

[java]  view plain copy
  1. public FragmentTransaction beginTransaction() {  
  2.         return new BackStackRecord(this);  
  3. }  

将此FragmentManager本身赋给了一个叫做BackStackRecord的类。并将此Manager的实例在内部用一个成员变量保存起来。用于做回退栈栈管理之类的操作。故名思义。这是用于做Fragment回退栈记录处理的类。接着往下看add方法。这个方法是定义在BackStackRecord类中。

[java]  view plain copy
  1. public FragmentTransaction add(int containerViewId, Fragment fragment, String tag) {  
  2.     doAddOp(containerViewId, fragment, tag, OP_ADD);  
  3.     return this;  
  4. }  


这个方法里面直接将成员变量交给一个叫做doAddOp的方法进行处理。再多传了一个标志位。用于区分add、remove、replace等操作:

[java]  view plain copy
  1. private void doAddOp(int containerViewId, Fragment fragment, String tag, int opcmd) {   
  2.         fragment.mFragmentManager = mManager;   
  3.   if (tag != null) {   
  4.             if (fragment.mTag != null && !tag.equals(fragment.mTag)) {   
  5.                 throw new IllegalStateException("Can't change tag of fragment "   
  6.                         + fragment + ": was " + fragment.mTag   
  7.                         + " now " + tag);   
  8.             }   
  9.             fragment.mTag = tag;   
  10.         }   
  11.  if (containerViewId != 0) {   
  12.             if (fragment.mFragmentId != 0 && fragment.mFragmentId != containerViewId) {   
  13.                 throw new IllegalStateException("Can't change container ID of fragment "   
  14.                         + fragment + ": was " + fragment.mFragmentId   
  15.                         + " now " + containerViewId);   
  16.             }   
  17.             fragment.mContainerId = fragment.mFragmentId = containerViewId;   
  18.         }   
  19.  Op op = new Op();   
  20.         op.cmd = opcmd;   
  21.         op.fragment = fragment;   
  22.         addOp(op);   
  23.  }  


这个方法中进行了一些保护性的判断。并 将containerViewId和tag赋给要添加的fragment.并将此fragment 放于一个Op的容器类中。类似我们常用的ViewHolder。它定义在BackStackRecord类中。而在add方法中传过来的参数OP_ADD。将它保存在了op类中的cmd变量中。

[java]  view plain copy
  1. static final class Op {   
  2.         Op next;   
  3.         Op prev;   
  4.         int cmd;   
  5.         Fragment fragment;   
  6.         int enterAnim;   
  7.         int exitAnim;   
  8.         int popEnterAnim;   
  9.         int popExitAnim;   
  10.         ArrayList<Fragment> removed;   
  11. }  


接着看addOp方法:

[java]  view plain copy
  1. void addOp(Op op) {   
  2.         if (mHead == null) {   
  3.             mHead = mTail = op;   
  4.         } else {   
  5.             op.prev = mTail;   
  6.             mTail.next = op;   
  7.             mTail = op;   
  8.         }   
  9.         op.enterAnim = mEnterAnim;   
  10.         op.exitAnim = mExitAnim;   
  11.         op.popEnterAnim = mPopEnterAnim;   
  12.         op.popExitAnim = mPopExitAnim;   
  13.         mNumOp++;   
  14.  }  


这个方法就是把封装了此fragment的op实例保存起来。并将设置的动画也加入其中。

到此add方法算是介绍完了。接下来是commit方法,它也是在BackStackRecord类中定义。

[java]  view plain copy
  1. public int commit() {   
  2.         return commitInternal(false);   
  3. }  


此处直接调用类中的commitInternal方法。传一个false进入。而我们知道fragment提交时还有一个叫做commitAllowingStateLoss的方法。这个方法内部也是直接调用commitInternal方法。但是传入一个true进入:

[java]  view plain copy
  1. int commitInternal(boolean allowStateLoss) {   
  2.         if (mCommitted) throw new IllegalStateException("commit already called");   
  3.         if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Commit: " + this);   
  4.         mCommitted = true;   
  5.         if (mAddToBackStack) {   
  6.             mIndex = mManager.allocBackStackIndex(this);   
  7.         } else {   
  8.             mIndex = -1;   
  9.         }   
  10.         mManager.enqueueAction(this, allowStateLoss);   
  11.         return mIndex;   
  12.  }  


这个方法中将对此fragment进行入栈操作。使用FragmentManagerImpl对象的enqueueAction方法将将回退栈记录管理类传回去。
下面回到FragmentManagerImpl类中:

[java]  view plain copy
  1. public void enqueueAction(Runnable action, boolean allowStateLoss) {   
  2.         if (!allowStateLoss) {   
  3.             checkStateLoss();   
  4.         }   
  5.         synchronized (this) {   
  6.             if (mActivity == null) {   
  7.                 throw new IllegalStateException("Activity has been destroyed");   
  8.             }   
  9.             if (mPendingActions == null) {   
  10.                 mPendingActions = new ArrayList<Runnable>();   
  11.             }   
  12.             mPendingActions.add(action);   
  13.             if (mPendingActions.size() == 1) {   
  14.                 mActivity.mHandler.removeCallbacks(mExecCommit);   
  15.                 mActivity.mHandler.post(mExecCommit);   
  16.             }   
  17.         }   
  18.  }  


allowStateLoss就是当时commitInternal传入的变量。在commit时为false。在commitAllowingStateLoss时为true。所以。在为false时。会调用checkStateLoss来检查状态。接着用了一个同步锁。在里面将BackStackRecord实例装入了mPendingActions的数组中。BackStackRecord是Runnable的子类。再将mExecCommit加入到主线程的handler中进行处理。这也是我们可以连续使用add、replace等在同一条语句的原因。在mExecCommit的Runnable对象中。调用了execPendingActions方法。

[java]  view plain copy
  1. public boolean execPendingActions() {   
  2.         if (mExecutingActions) {   
  3.             throw new IllegalStateException("Recursive entry to executePendingTransactions");   
  4.         }   
  5.            
  6.         if (Looper.myLooper() != mActivity.mHandler.getLooper()) {   
  7.             throw new IllegalStateException("Must be called from main thread of process");   
  8.         }   
  9.   boolean didSomething = false;  
  10.   while (true) {  
  11.             int numActions;   
  12.                
  13.             synchronized (this) {   
  14.                 if (mPendingActions == null || mPendingActions.size() == 0) {   
  15.                     break;   
  16.                 }   
  17.                    
  18.                 numActions = mPendingActions.size();   
  19.                 if (mTmpActions == null || mTmpActions.length < numActions) {   
  20.                     mTmpActions = new Runnable[numActions];   
  21.                 }   
  22.                 mPendingActions.toArray(mTmpActions);   
  23.                 mPendingActions.clear();   
  24.                 mActivity.mHandler.removeCallbacks(mExecCommit);   
  25.             }   
  26.                
  27.             mExecutingActions = true;   
  28.             for (int i=0; i<numActions; i++) {   
  29.                 mTmpActions[i].run();   
  30.                 mTmpActions[i] = null;   
  31.             }   
  32.             mExecutingActions = false;   
  33.             didSomething = true;   
  34.         }   
  35.  if (mHavePendingDeferredStart) {  
  36.             boolean loadersRunning = false;   
  37.             for (int i=0; i<mActive.size(); i++) {   
  38.                 Fragment f = mActive.get(i);   
  39.                 if (f != null && f.mLoaderManager != null) {   
  40.                     loadersRunning |= f.mLoaderManager.hasRunningLoaders();   
  41.                 }   
  42.             }   
  43.             if (!loadersRunning) {   
  44.                 mHavePendingDeferredStart = false;   
  45.                 startPendingDeferredFragments();   
  46.             }   
  47.         }   
  48.         return didSomething;   
  49.  }  


这个方法中用了一个while(true)循环对mPendingActions进行操作。所以接着看mPendingActions里面的Runnable对象的run方法。而这个里面保存的是BackStackRecord对象。所以又回到BackStackRecord类中:

[java]  view plain copy
  1. public void run() {  
  2.         if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Run: " + this);  
  3.         if (mAddToBackStack) {  
  4.             if (mIndex < 0) {  
  5.                 throw new IllegalStateException("addToBackStack() called after commit()");  
  6.             }  
  7.         }  
  8.         bumpBackStackNesting(1);  
  9.         Op op = mHead;  
  10.         while (op != null) {  
  11.             switch (op.cmd) {  
  12.                 case OP_ADD: {  
  13.                     Fragment f = op.fragment;  
  14.                     f.mNextAnim = op.enterAnim;  
  15.                     mManager.addFragment(f, false);  
  16.                 } break;  
  17.                 case OP_REPLACE: {  
  18.                     Fragment f = op.fragment;  
  19.                     if (mManager.mAdded != null) {  
  20.                         for (int i=0; i<mManager.mAdded.size(); i++) {  
  21.                             Fragment old = mManager.mAdded.get(i);  
  22.                             if (FragmentManagerImpl.DEBUG) Log.v(TAG,  
  23.                                     "OP_REPLACE: adding=" + f + " old=" + old);  
  24.                             if (f == null || old.mContainerId == f.mContainerId) {  
  25.                                 if (old == f) {  
  26.                                     op.fragment = f = null;  
  27.                                 } else {  
  28.                                     if (op.removed == null) {  
  29.                                         op.removed = new ArrayList<Fragment>();  
  30.                                     }  
  31.                                     op.removed.add(old);  
  32.                                     old.mNextAnim = op.exitAnim;  
  33.                                     if (mAddToBackStack) {  
  34.                                         old.mBackStackNesting += 1;  
  35.                                         if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Bump nesting of "  
  36.                                                 + old + " to " + old.mBackStackNesting);  
  37.                                     }  
  38.                                     mManager.removeFragment(old, mTransition, mTransitionStyle);  
  39.                                 }  
  40.                             }  
  41.                         }  
  42.                     }  
  43.                     if (f != null) {  
  44.                         f.mNextAnim = op.enterAnim;  
  45.                         mManager.addFragment(f, false);  
  46.                     }  
  47.                 } break;  
  48.                 case OP_REMOVE: {  
  49.                     Fragment f = op.fragment;  
  50.                     f.mNextAnim = op.exitAnim;  
  51.                     mManager.removeFragment(f, mTransition, mTransitionStyle);  
  52.                 } break;  
  53.                 case OP_HIDE: {  
  54.                     Fragment f = op.fragment;  
  55.                     f.mNextAnim = op.exitAnim;  
  56.                     mManager.hideFragment(f, mTransition, mTransitionStyle);  
  57.                 } break;  
  58.                 case OP_SHOW: {  
  59.                     Fragment f = op.fragment;  
  60.                     f.mNextAnim = op.enterAnim;  
  61.                     mManager.showFragment(f, mTransition, mTransitionStyle);  
  62.                 } break;  
  63.                 case OP_DETACH: {  
  64.                     Fragment f = op.fragment;  
  65.                     f.mNextAnim = op.exitAnim;  
  66.                     mManager.detachFragment(f, mTransition, mTransitionStyle);  
  67.                 } break;  
  68.                 case OP_ATTACH: {  
  69.                     Fragment f = op.fragment;  
  70.                     f.mNextAnim = op.enterAnim;  
  71.                     mManager.attachFragment(f, mTransition, mTransitionStyle);  
  72.                 } break;  
  73.                 default: {  
  74.                     throw new IllegalArgumentException("Unknown cmd: " + op.cmd);  
  75.                 }  
  76.             }  
  77.             op = op.next;  
  78.         }  
  79.         mManager.moveToState(mManager.mCurState, mTransition,  
  80.                 mTransitionStyle, true);  
  81.         if (mAddToBackStack) {  
  82.             mManager.addBackStackState(this);  
  83.         }  
  84.     }  


可以看见。在run方法中。它也进行了一个while(true)循环。在里面从Op中一个个的通过next变量取出下一个Op实例。每个Op实例包装一个Fragment实例。方法内部用switch对不同的操作进行区别运行。此处我们看OP_ADD中的代码。它把Fragment实例和它的进行动画取出来。使用FragmentManager管理类addFragment。在addFragment方法中。此将Fragment加入了一个叫做mAdded的成员变量中。类型是ArrayList。范型是Fragment。代表已加入的fragment。然后跳出switch语句。执行FragmentManagerImpl中的moveToState方法。

[java]  view plain copy
  1. void moveToState(int newState, int transit, int transitStyle, boolean always) {  
  2.         if (mActivity == null && newState != Fragment.INITIALIZING) {  
  3.             throw new IllegalStateException("No activity");  
  4.         }  
  5.          
  6.         if (!always && mCurState == newState) {  
  7.             return;  
  8.         }  
  9.          
  10.         mCurState = newState;  
  11.         if (mActive != null) {  
  12.             boolean loadersRunning = false;  
  13.             for (int i=0; i<mActive.size(); i++) {  
  14.                 Fragment f = mActive.get(i);  
  15.                 if (f != null) {  
  16.                     moveToState(f, newState, transit, transitStyle, false);  
  17.                     if (f.mLoaderManager != null) {  
  18.                         loadersRunning |= f.mLoaderManager.hasRunningLoaders();  
  19.                     }  
  20.                 }  
  21.             }  
  22.             if (!loadersRunning) {  
  23.                 startPendingDeferredFragments();  
  24.             }  
  25.             if (mNeedMenuInvalidate && mActivity != null && mCurState == Fragment.RESUMED) {  
  26.                 mActivity.invalidateOptionsMenu();  
  27.                 mNeedMenuInvalidate = false;  
  28.             }  
  29.         }  
  30.     }  


一般我们commit的地方在Activity的super.onCreate之后。此处newState为ACTIVITY_CREATED 。状态值总共有如下几个:
[java]  view plain copy
  1. static final int INVALID_STATE = -1;   // Invalid state used as a null value.  
  2. static final int INITIALIZING = 0;     // Not yet created.  
  3. static final int CREATED = 1;          // Created.  
  4. static final int ACTIVITY_CREATED = 2// The activity has finished its creation.  
  5. static final int STOPPED = 3;          // Fully created, not started.  
  6. static final int STARTED = 4;          // Created and started, not resumed.  
  7. static final int RESUMED = 5;          // Created started and resumed.  


在此方法中。程序调用五个参数的moveToState

[java]  view plain copy
  1. void moveToState(Fragment f, int newState, int transit, int transitionStyle,  
  2.             boolean keepActive) {  
  3.         // Fragments that are not currently added will sit in the onCreate() state.  
  4.         if ((!f.mAdded || f.mDetached) && newState > Fragment.CREATED) {  
  5.             newState = Fragment.CREATED;  
  6.         }  
  7.         if (f.mRemoving && newState > f.mState) {  
  8.             // While removing a fragment, we can't change it to a higher state.  
  9.             newState = f.mState;  
  10.         }  
  11.         // Defer start if requested; don't allow it to move to STARTED or higher  
  12.         // if it's not already started.  
  13.         if (f.mDeferStart && f.mState < Fragment.STARTED && newState > Fragment.STOPPED) {  
  14.             newState = Fragment.STOPPED;  
  15.         }  
  16.         if (f.mState < newState) {  
  17.             // For fragments that are created from a layout, when restoring from  
  18.             // state we don't want to allow them to be created until they are  
  19.             // being reloaded from the layout.  
  20.             if (f.mFromLayout && !f.mInLayout) {  
  21.                 return;  
  22.             }  
  23.             if (f.mAnimatingAway != null) {  
  24.                 // The fragment is currently being animated... but! Now we  
  25.                 // want to move our state back up. Give up on waiting for the  
  26.                 // animation, move to whatever the final state should be once  
  27.                 // the animation is done, and then we can proceed from there.  
  28.                 f.mAnimatingAway = null;  
  29.                 moveToState(f, f.mStateAfterAnimating, 00true);  
  30.             }  
  31.             switch (f.mState) {  
  32.                 case Fragment.INITIALIZING:  
  33.                     if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);  
  34.                     if (f.mSavedFragmentState != null) {  
  35.                         f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(  
  36.                                 FragmentManagerImpl.VIEW_STATE_TAG);  
  37.                         f.mTarget = getFragment(f.mSavedFragmentState,  
  38.                                 FragmentManagerImpl.TARGET_STATE_TAG);  
  39.                         if (f.mTarget != null) {  
  40.                             f.mTargetRequestCode = f.mSavedFragmentState.getInt(  
  41.                                     FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);  
  42.                         }  
  43.                         f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(  
  44.                                 FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);  
  45.                         if (!f.mUserVisibleHint) {  
  46.                             f.mDeferStart = true;  
  47.                             if (newState > Fragment.STOPPED) {  
  48.                                 newState = Fragment.STOPPED;  
  49.                             }  
  50.                         }  
  51.                     }  
  52.                     f.mActivity = mActivity;  
  53.                     f.mParentFragment = mParent;  
  54.                     f.mFragmentManager = mParent != null  
  55.                             ? mParent.mChildFragmentManager : mActivity.mFragments;  
  56.                     f.mCalled = false;  
  57.                     f.onAttach(mActivity);  
  58.                     if (!f.mCalled) {  
  59.                         throw new SuperNotCalledException("Fragment " + f  
  60.                                 + " did not call through to super.onAttach()");  
  61.                     }  
  62.                     if (f.mParentFragment == null) {  
  63.                         mActivity.onAttachFragment(f);  
  64.                     }  
  65.                     if (!f.mRetaining) {  
  66.                         f.performCreate(f.mSavedFragmentState);  
  67.                     }  
  68.                     f.mRetaining = false;  
  69.                     if (f.mFromLayout) {  
  70.                         // For fragments that are part of the content view  
  71.                         // layout, we need to instantiate the view immediately  
  72.                         // and the inflater will take care of adding it.  
  73.                         f.mView = f.performCreateView(f.getLayoutInflater(  
  74.                                 f.mSavedFragmentState), null, f.mSavedFragmentState);  
  75.                         if (f.mView != null) {  
  76.                             f.mInnerView = f.mView;  
  77.                             f.mView = NoSaveStateFrameLayout.wrap(f.mView);  
  78.                             if (f.mHidden) f.mView.setVisibility(View.GONE);  
  79.                             f.onViewCreated(f.mView, f.mSavedFragmentState);  
  80.                         } else {  
  81.                             f.mInnerView = null;  
  82.                         }  
  83.                     }  
  84.                 case Fragment.CREATED:  
  85.                     if (newState > Fragment.CREATED) {  
  86.                         if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);  
  87.                         if (!f.mFromLayout) {  
  88.                             ViewGroup container = null;  
  89.                             if (f.mContainerId != 0) {  
  90.                                 container = (ViewGroup)mContainer.findViewById(f.mContainerId);  
  91.                                 if (container == null && !f.mRestored) {  
  92.                                     throwException(new IllegalArgumentException(  
  93.                                             "No view found for id 0x"  
  94.                                             + Integer.toHexString(f.mContainerId) + " ("  
  95.                                             + f.getResources().getResourceName(f.mContainerId)  
  96.                                             + ") for fragment " + f));  
  97.                                 }  
  98.                             }  
  99.                             f.mContainer = container;  
  100.                             f.mView = f.performCreateView(f.getLayoutInflater(  
  101.                                     f.mSavedFragmentState), container, f.mSavedFragmentState);  
  102.                             if (f.mView != null) {  
  103.                                 f.mInnerView = f.mView;  
  104.                                 f.mView = NoSaveStateFrameLayout.wrap(f.mView);  
  105.                                 if (container != null) {  
  106.                                     Animation anim = loadAnimation(f, transit, true,  
  107.                                             transitionStyle);  
  108.                                     if (anim != null) {  
  109.                                         f.mView.startAnimation(anim);  
  110.                                     }  
  111.                                     container.addView(f.mView);  
  112.                                 }  
  113.                                 if (f.mHidden) f.mView.setVisibility(View.GONE);  
  114.                                 f.onViewCreated(f.mView, f.mSavedFragmentState);  
  115.                             } else {  
  116.                                 f.mInnerView = null;  
  117.                             }  
  118.                         }  
  119.                         f.performActivityCreated(f.mSavedFragmentState);  
  120.                         if (f.mView != null) {  
  121.                             f.restoreViewState(f.mSavedFragmentState);  
  122.                         }  
  123.                         f.mSavedFragmentState = null;  
  124.                     }  
  125.                 case Fragment.ACTIVITY_CREATED:  
  126.                 case Fragment.STOPPED:  
  127.                     if (newState > Fragment.STOPPED) {  
  128.                         if (DEBUG) Log.v(TAG, "moveto STARTED: " + f);  
  129.                         f.performStart();  
  130.                     }  
  131.                 case Fragment.STARTED:  
  132.                     if (newState > Fragment.STARTED) {  
  133.                         if (DEBUG) Log.v(TAG, "moveto RESUMED: " + f);  
  134.                         f.mResumed = true;  
  135.                         f.performResume();  
  136.                         f.mSavedFragmentState = null;  
  137.                         f.mSavedViewState = null;  
  138.                     }  
  139.             }  
  140.         } else if (f.mState > newState) {  
  141.             switch (f.mState) {  
  142.                 case Fragment.RESUMED:  
  143.                     if (newState < Fragment.RESUMED) {  
  144.                         if (DEBUG) Log.v(TAG, "movefrom RESUMED: " + f);  
  145.                         f.performPause();  
  146.                         f.mResumed = false;  
  147.                     }  
  148.                 case Fragment.STARTED:  
  149.                     if (newState < Fragment.STARTED) {  
  150.                         if (DEBUG) Log.v(TAG, "movefrom STARTED: " + f);  
  151.                         f.performStop();  
  152.                     }  
  153.                 case Fragment.STOPPED:  
  154.                     if (newState < Fragment.STOPPED) {  
  155.                         if (DEBUG) Log.v(TAG, "movefrom STOPPED: " + f);  
  156.                         f.performReallyStop();  
  157.                     }  
  158.                 case Fragment.ACTIVITY_CREATED:  
  159.                     if (newState < Fragment.ACTIVITY_CREATED) {  
  160.                         if (DEBUG) Log.v(TAG, "movefrom ACTIVITY_CREATED: " + f);  
  161.                         if (f.mView != null) {  
  162.                             // Need to save the current view state if not  
  163.                             // done already.  
  164.                             if (!mActivity.isFinishing() && f.mSavedViewState == null) {  
  165.                                 saveFragmentViewState(f);  
  166.                             }  
  167.                         }  
  168.                         f.performDestroyView();  
  169.                         if (f.mView != null && f.mContainer != null) {  
  170.                             Animation anim = null;  
  171.                             if (mCurState > Fragment.INITIALIZING && !mDestroyed) {  
  172.                                 anim = loadAnimation(f, transit, false,  
  173.                                         transitionStyle);  
  174.                             }  
  175.                             if (anim != null) {  
  176.                                 final Fragment fragment = f;  
  177.                                 f.mAnimatingAway = f.mView;  
  178.                                 f.mStateAfterAnimating = newState;  
  179.                                 anim.setAnimationListener(new AnimationListener() {  
  180.                                     @Override  
  181.                                     public void onAnimationEnd(Animation animation) {  
  182.                                         if (fragment.mAnimatingAway != null) {  
  183.                                             fragment.mAnimatingAway = null;  
  184.                                             moveToState(fragment, fragment.mStateAfterAnimating,  
  185.                                                     00false);  
  186.                                         }  
  187.                                     }  
  188.                                     @Override  
  189.                                     public void onAnimationRepeat(Animation animation) {  
  190.                                     }  
  191.                                     @Override  
  192.                                     public void onAnimationStart(Animation animation) {  
  193.                                     }  
  194.                                 });  
  195.                                 f.mView.startAnimation(anim);  
  196.                             }  
  197.                             f.mContainer.removeView(f.mView);  
  198.                         }  
  199.                         f.mContainer = null;  
  200.                         f.mView = null;  
  201.                         f.mInnerView = null;  
  202.                     }  
  203.                 case Fragment.CREATED:  
  204.                     if (newState < Fragment.CREATED) {  
  205.                         if (mDestroyed) {  
  206.                             if (f.mAnimatingAway != null) {  
  207.                                 // The fragment's containing activity is  
  208.                                 // being destroyed, but this fragment is  
  209.                                 // currently animating away. Stop the  
  210.                                 // animation right now -- it is not needed,  
  211.                                 // and we can't wait any more on destroying  
  212.                                 // the fragment.  
  213.                                 View v = f.mAnimatingAway;  
  214.                                 f.mAnimatingAway = null;  
  215.                                 v.clearAnimation();  
  216.                             }  
  217.                         }  
  218.                         if (f.mAnimatingAway != null) {  
  219.                             // We are waiting for the fragment's view to finish  
  220.                             // animating away. Just make a note of the state  
  221.                             // the fragment now should move to once the animation  
  222.                             // is done.  
  223.                             f.mStateAfterAnimating = newState;  
  224.                             newState = Fragment.CREATED;  
  225.                         } else {  
  226.                             if (DEBUG) Log.v(TAG, "movefrom CREATED: " + f);  
  227.                             if (!f.mRetaining) {  
  228.                                 f.performDestroy();  
  229.                             }  
  230.                             f.mCalled = false;  
  231.                             f.onDetach();  
  232.                             if (!f.mCalled) {  
  233.                                 throw new SuperNotCalledException("Fragment " + f  
  234.                                         + " did not call through to super.onDetach()");  
  235.                             }  
  236.                             if (!keepActive) {  
  237.                                 if (!f.mRetaining) {  
  238.                                     makeInactive(f);  
  239.                                 } else {  
  240.                                     f.mActivity = null;  
  241.                                     f.mFragmentManager = null;  
  242.                                 }  
  243.                             }  
  244.                         }  
  245.                     }  
  246.             }  
  247.         }  
  248.          
  249.         f.mState = newState;  
  250.     }  


重要的终于到了啊!这个方法中会先依次走INITIALIZING,CREATED,ACTIVITY_CREATED代码段。之后会根据Activity的生命周期走自己相应的生命周期函数。在此对应的是STARTED,RESUMED;
由于是初次加载Fragment。所以f.mState是小于newState的。所以走的都是f.mState<newState中的switch语句。
首先看INITIALIZING状态:

[java]  view plain copy
  1. case Fragment.INITIALIZING:  
  2.                     if (DEBUG) Log.v(TAG, "moveto CREATED: " + f);  
  3.                     if (f.mSavedFragmentState != null) {  
  4.                         f.mSavedViewState = f.mSavedFragmentState.getSparseParcelableArray(  
  5.                                 FragmentManagerImpl.VIEW_STATE_TAG);  
  6.                         f.mTarget = getFragment(f.mSavedFragmentState,  
  7.                                 FragmentManagerImpl.TARGET_STATE_TAG);  
  8.                         if (f.mTarget != null) {  
  9.                             f.mTargetRequestCode = f.mSavedFragmentState.getInt(  
  10.                                     FragmentManagerImpl.TARGET_REQUEST_CODE_STATE_TAG, 0);  
  11.                         }  
  12.                         f.mUserVisibleHint = f.mSavedFragmentState.getBoolean(  
  13.                                 FragmentManagerImpl.USER_VISIBLE_HINT_TAG, true);  
  14.                         if (!f.mUserVisibleHint) {  
  15.                             f.mDeferStart = true;  
  16.                             if (newState > Fragment.STOPPED) {  
  17.                                 newState = Fragment.STOPPED;  
  18.                             }  
  19.                         }  
  20.                     }  
  21.                     f.mActivity = mActivity;  
  22.                     f.mFragmentManager = mActivity.mFragments;  
  23.                     f.mCalled = false;  
  24.                     f.onAttach(mActivity);  
  25.                     if (!f.mCalled) {  
  26.                         throw new SuperNotCalledException("Fragment " + f  
  27.                                 + " did not call through to super.onAttach()");  
  28.                     }  
  29.                     mActivity.onAttachFragment(f);  
  30.                       
  31.                     if (!f.mRetaining) {  
  32.                         f.mCalled = false;  
  33.                         f.onCreate(f.mSavedFragmentState);  
  34.                         if (!f.mCalled) {  
  35.                             throw new SuperNotCalledException("Fragment " + f  
  36.                                     + " did not call through to super.onCreate()");  
  37.                         }  
  38.                     }  
  39.                     f.mRetaining = false;  
  40.                     if (f.mFromLayout) {  
  41.                         // For fragments that are part of the content view  
  42.                         // layout, we need to instantiate the view immediately  
  43.                         // and the inflater will take care of adding it.  
  44.                         f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState),  
  45.                                 null, f.mSavedFragmentState);  
  46.                         if (f.mView != null) {  
  47.                             f.mView.setSaveFromParentEnabled(false);  
  48.                             if (f.mHidden) f.mView.setVisibility(View.GONE);  
  49.                             f.onViewCreated(f.mView, f.mSavedFragmentState);  
  50.                         }  
  51.                     }  
  52. case Fragment.CREATED:  


在f.mSavedFragmentState != null这个条件判断语句块中。是屏幕切换时或因其他原因引起的fragment被销毁后重新恢复时走的语句块。在此不用理会。接着后面,熟悉的代码出现了,f.onAttach(mActivity),第一个生命周期方法。这里面就可以拿到与此fragment相绑定的Activity的实例。接着往下看。f.onCreate(f.mSavedFragmentState)。走onCreate回调了。
而f.mFromLayout在此时为false。故不用理会。

接着。来看CREATED状态:
[java]  view plain copy
  1. case Fragment.CREATED:  
  2.                     if (newState > Fragment.CREATED) {  
  3.                         if (DEBUG) Log.v(TAG, "moveto ACTIVITY_CREATED: " + f);  
  4.                         if (!f.mFromLayout) {  
  5.                             ViewGroup container = null;  
  6.                             if (f.mContainerId != 0) {  
  7.                                 container = (ViewGroup)mActivity.findViewById(f.mContainerId);  
  8.                                 if (container == null && !f.mRestored) {  
  9.                                     throw new IllegalArgumentException("No view found for id 0x"  
  10.                                             + Integer.toHexString(f.mContainerId)  
  11.                                             + " for fragment " + f);  
  12.                                 }  
  13.                             }  
  14.                             f.mContainer = container;  
  15.                             f.mView = f.onCreateView(f.getLayoutInflater(f.mSavedFragmentState),  
  16.                                     container, f.mSavedFragmentState);  
  17.                             if (f.mView != null) {  
  18.                                 f.mView.setSaveFromParentEnabled(false);  
  19.                                 if (container != null) {  
  20.                                     Animator anim = loadAnimator(f, transit, true,  
  21.                                             transitionStyle);  
  22.                                     if (anim != null) {  
  23.                                         anim.setTarget(f.mView);  
  24.                                         anim.start();  
  25.                                     }  
  26.                                     container.addView(f.mView);  
  27.                                 }  
  28.                                 if (f.mHidden) f.mView.setVisibility(View.GONE);  
  29.                                 f.onViewCreated(f.mView, f.mSavedFragmentState);  
  30.                             }  
  31.                         }  
  32.                           
  33.                         f.mCalled = false;  
  34.                         f.onActivityCreated(f.mSavedFragmentState);  
  35.                         if (!f.mCalled) {  
  36.                             throw new SuperNotCalledException("Fragment " + f  
  37.                                     + " did not call through to super.onActivityCreated()");  
  38.                         }  
  39.                         if (f.mView != null) {  
  40.                             f.restoreViewState();  
  41.                         }  
  42.                         f.mSavedFragmentState = null;  
  43.                     }  
  44. case Fragment.ACTIVITY_CREATED:  


重点来了!newState此时的值为ACTIVITY_CREATED。故可以进入语句块,在内部先通过Activity的findViewById方法通过add的containerid来得到要添加fragment的ViewGroup。再将其赋给fragment的mContainer成员变量中。接下来通过fragment的onCreateView回调。将创建的view放入fragment的view成员变量中。接下来就是加载fragment的动画以及将创建的view通过addView方法放于容器中了。至此。成功将fragment嵌入到了界面上
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值