使用Fragment时。可以经过用户交互来运行一些动做。比方添加、移除、替换等。java
所有这些改变构成一个集合,这个集合被叫作一个transaction。ide
可以调用FragmentTransaction中的方法来处理这个transaction,并且可以将transaction存进由activity管理的back stack中,这样用户就可以进行fragment变化的回退操做。post
可以这样获得FragmentTransaction类的实例:this
FragmentManager mFragmentManager = getSupportFragmentManager(); FragmentTransaction mFragmentTransaction = mFragmentManager.beginTransaction();
在commit()方法以前,你可以调用addToBackStack(),把这个transaction增长back stack中去,这个back stack是由activity管理的。当用户按返回键时,就会回到上一个fragment的状态。
你仅仅能在activity存储它的状态(当用户要离开activity时)以前调用commit()。假设在存储状态以后调用commit()。将会抛出一个异常。线程
这是因为当activity再次被恢复时commit以后的状态将丢失。假设丢失也不要紧。那么使用commitAllowingStateLoss()方法。
code
/** * Return the FragmentManager for interacting with fragments associated * with this activity. */ public FragmentManager getSupportFragmentManager() { return mFragments; }
/** * Container for fragments associated with an activity. */ final class FragmentManagerImpl extends FragmentManager { ........ @Override public FragmentTransaction beginTransaction() { return new BackStackRecord(this); } ........ }
/** * @hide Entry of an operation on the fragment back stack. */ final class BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry, Runnable { .......... public int commit() { return commitInternal(false); } public int commitAllowingStateLoss() { return commitInternal(true); } int commitInternal(boolean allowStateLoss) { if (mCommitted) throw new IllegalStateException("commit already called"); if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Commit: " + this); mCommitted = true; if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this); } else { mIndex = -1; } mManager.enqueueAction(this, allowStateLoss); return mIndex; } .......... }
让咱们回到FragmentManager,看这种方法是怎样操做的。orm
咱们找到这种方法。
blog
/** * @hide Entry of an operation on the fragment back stack. */ final class BackStackRecord extends FragmentTransaction implements FragmentManager.BackStackEntry, Runnable { .......... public int commit() { return commitInternal(false); } public int commitAllowingStateLoss() { return commitInternal(true); } int commitInternal(boolean allowStateLoss) { if (mCommitted) throw new IllegalStateException("commit already called"); if (FragmentManagerImpl.DEBUG) Log.v(TAG, "Commit: " + this); mCommitted = true; if (mAddToBackStack) { mIndex = mManager.allocBackStackIndex(this); } else { mIndex = -1; } mManager.enqueueAction(this, allowStateLoss); return mIndex; } .......... }
private void checkStateLoss() { if (mStateSaved) { throw new IllegalStateException( "Can not perform this action after onSaveInstanceState"); } if (mNoTransactionsBecause != null) { throw new IllegalStateException( "Can not perform this action inside of " + mNoTransactionsBecause); } }ok,到这里。真相总算大明。当使用commit方法时,系统将进行状态推断,假设状态(mStateSaved)已经保存,将发生"Can not perform this action after onSaveInstanceState"错误。 假设mNoTransactionsBecause已经存在,将发生"Can not perform this action inside of " + mNoTransactionsBecause错误。