使用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錯誤。