2017-02-28 77 views
8

我打電話popBackStack()在活動onCreate()方法,但我得到異常:popBackStack和commitAllowingStateLoss

Caused by java.lang.IllegalStateException: Can not perform this action after onSaveInstanceState 

android.app.FragmentManagerImpl.checkStateLoss (FragmentManager.java:1428) 
android.app.FragmentManagerImpl.enqueueAction (FragmentManager.java:1446) 
android.app.FragmentManagerImpl.popBackStack (FragmentManager.java:572) 

我明白,解決這個異常的一種方式,只要你是對的影響OK UI和最終用戶是調用commitAllowingStateLoss。

的問題是,與popBackStack沒有委託調用。有沒有其他方法可以調用popBackStack並允許狀態丟失?

我應該說,我在onPostResume這樣做的,得到這個例外。

+0

我認爲這個錯誤當您在不活動的活動上調用popBackStack()時會引發這個問題。發佈代碼以進一步調試 – arjun

+0

@arjun我從onPostResume中調用popBackStack,根據我可以找到的所有參考,這是一個安全的地方,在應用程序恢復後調用它。我不能發佈任何更多的代碼,因爲應用程序是巨大的,但歸結爲在onPostResume中調用popBackStack。當應用程序安全恢復後,肯定會有一些地方可以重新初始化GUI? – user3690202

+0

正如@arjun建議的,你有沒有嘗試在'onResumeFragments()'中執行它? – azizbekian

回答

1

大量的研究後,我得出的結論是,這是不可能的,當活動恢復在Android操縱片段。根據所提到的博客文章,我嘗試過onPostResume()和onResumeFragments()從後臺堆棧中彈出片段,並且在發佈到產品時都會導致間歇性崩潰。

這種現實的不利之處在於,如果您希望顯示級別片段的結尾,然後顯示插頁式廣告,然後顯示下一級別(作爲級別片段結尾的不同片段),則不可能使用碎片。

對於我的個人情況,我刪除從我的應用程序的所有片段。我繼續使用佈局,因爲在XML中編輯用戶界面非常有用,但片段生命週期在當前狀態下不可用,所以我推出了自己的「片段」子系統,但更好,因爲它可以通過活動onResume進行操作。

我希望有一天,谷歌將解決這個問題,因爲它使爲Android真的不愉快的發展。無論如何,如果有人需要使用的片段,但並不像典型的onSaveInstanceState例外,你總是會得到的,這裏是我的「GameScreen」實現(它就像一個片段,只有更好)

/** 
* GameScreen 
*/ 
public class GameScreen { 

    private int id; 
    private View view; 
    private ViewGroup viewGroup; 
    protected MainActivity mainActivity; 

    public GameScreen(MainActivity mainActivity, int id) { 
     this.mainActivity = mainActivity; 
     this.id = id; 
    } 

    public void create(LayoutInflater layoutInflater, ViewGroup viewGroup) { 
     this.viewGroup = viewGroup; 
     view = layoutInflater.inflate(id, viewGroup, false); 
     viewGroup.addView(view); 
    } 

    public void show() { 
     for (int i = 0; i < viewGroup.getChildCount(); i++) { 
      View v = viewGroup.getChildAt(i); 
      if (v != view) { 
       v.setVisibility(View.INVISIBLE); 
      } 
     } 

     view.setVisibility(View.VISIBLE); 
    } 
} 
0

我下面從這個博客http://www.androiddesignpatterns.com/2013/08/fragment-transaction-commit-state-loss.html

此錯誤可能拋出,如果commit()在任何活動回調恢復活動狀態之前可以調用。做popBackStack() 所以,最好的地方是onResumeFragments()回調

popBackStack()確實有commit()內部調用因爲它的作用僅僅是扭轉堆棧中的最後一個FragmentTransaction

+0

我沒有使用FragmentActivity,只有Activity。那篇博客文章(我已經閱讀過)已經__ guarantees__在onPostResume()中做了這個工作 - 這顯然不會。因此,該博客包含的信息基本上是錯誤的。 – user3690202

+0

,但推薦使用'AppCombatActivity',它擴展'FragamentActivity',你可以嘗試使用'onResumeFragments()'回調 – arjun

+0

你能確切地推薦哪裏推薦?它當然不是在Android Studio中創建新的片段活動項目時生成的默認基類。 – user3690202

相關問題