此文包含java.lang.IllegalStateException的4種情形:
1.java.lang.IllegalStateException: Fragment already added
**2.java.lang.IllegalStateException: Fragment MyFragment{xxx} not attached to Activity **
3.java.lang.IllegalStateException: Fragment already active
**4.java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
**
問題1:java.lang.IllegalStateException: Fragment already added異常的處理。
當快速雙擊調(diào)用FragmentTransaction.add()方法添加fragmentA,而fragmentA不是每次單獨生成的,就會引起這個異常。
DialogFragment.show()內(nèi)部調(diào)用了FragmentTransaction.add()方法,所以調(diào)用DialogFragment.show()方法時候也可能會出現(xiàn)這個異常。
解決方法:
在add()方法時候,先判斷fragmentA.isAdded(),
如下調(diào)用可以避免該異常:
if(!fragmentA.isAdded()){
FragmentManager manager = ((FragmentActivity)context).getSupportFragmentManager();
FragmentTransaction ft = manager.beginTransaction();
ft.add(fragmentA, "fragment_name");
ft.commit();
}
問題2:java.lang.IllegalStateException: Fragment MyFragment{410f6060} not attached to Activity
出現(xiàn)該異常,是因為Fragment的還沒有Attach到Activity時,調(diào)用了如getResource()等,需要上下文Content的函數(shù)。
解決方法:
就是等將調(diào)用的代碼寫在OnStart()中。
另外一種解決方法:
主要是在調(diào)用:getResources().getString(R.string.app_name); 之前增加一個判斷isAdded(),
參考:
http://stackoverflow.com/questions/10919240/fragment-myfragment-not-attached-to-activity
http://stackoverflow.com/questions/6870325/android-compatibility-package-fragment-not-attached-to-activity
問題3:java.lang.IllegalStateException: Fragment already active
在 Fragment 沒有被添加到 FragmentManager 之前,我們可以通過 Fragment.setArguments() 來設置參數(shù),并在 Fragment 中,使用 getArguments() 來取得參數(shù)。在 Fragment 被添加到 FragmentManager 后,一旦被使用,我們再次調(diào)用 setArguments() 將會導致 java.lang.IllegalStateException: Fragment already active 異常。
解決方法:
可以使用setter和getter方法進行數(shù)據(jù)的存儲和獲取。
/**看幾個關(guān)鍵點,getItem方法返回新建的Fragment對象,
*instantiateItem方法先調(diào)用父類的方法獲得已經(jīng)存在的Fragment,
*然后用Fragment中的setter添加屬性,
*在getItemPosition方法中總是返回POSITION_NONE。
*/
1 @Override
2 public Fragment getItem(int position) {
3 MyFragment f = new MyFragment();
4 return f;
5 }
6
7 @Override
8 public Object instantiateItem(ViewGroup container, int position) {
9 MyFragment f = (MyFragment) super.instantiateItem(container, position);
10 String title = mList.get(position);
11 f.setTitle(title);
12 return f;
13 }
14
15 @Override
16 public int getItemPosition(Object object) {
17 return PagerAdapter.POSITION_NONE;
18 }
參考:
http://fattycat.me/something-about-fragment/(推薦閱讀)
http://stackoverflow.com/questions/10364478/got-exception-fragment-already-active/15084683
問題4:java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState
在使用Fragment保存參數(shù)的時候,可能是因為需要保存的參數(shù)比較大或者比較多,這種情況下頁會引起異常。比如代碼:
Bundle b = new Bundle();
b.putParcelable("bitmap", bitmap2);
imageRecognitionFragment.setArguments(b);
設置好參數(shù),并且添加hide(),add(),方法之后,需要commit(),來實現(xiàn)兩個Fragment跳轉(zhuǎn)的時候,這種情形下參數(shù)需要進行系統(tǒng)保存,但是這個時候你已經(jīng)實現(xiàn)了跳轉(zhuǎn),系統(tǒng)參數(shù)卻沒有保存。此時就會報java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState異常。
分析原因:
你并不需要系統(tǒng)保存的參數(shù),只要你自己設置的參數(shù)能夠傳遞過去,在另外一個Fragment里能夠順利接受就行了,現(xiàn)在android里提供了另外一種形式的提交方式commitAllowingStateLoss(),從名字上就能看出,這種提交是允許狀態(tài)值丟失的。到此問題得到完美解決,值的傳遞是你自己控制的。
解決方法:
將commit()改成commitAllowingStateLoss()即可。這里也說一下另外一個問題,bitmap 也可以通過Bundle傳遞的,使用putParacelable就可以了。