此問題通常是您的應用程序體系結構存在更深層問題的症狀。當視圖層和業務邏輯層之間沒有適當的關注點分離時,您往往會看到它。
我想你直接在Activity/Fragment中做一些異步工作,然後在結果返回時嘗試做一個Fragment事務。
有很多的事情可以做,來解決這個問題:
不要使用碎片
有幾乎從來沒有需要使用一個片段 - 90%的時間你可以使用ViewGroup達到相同的結果,並避免所有的生命週期令人頭疼,隨機崩潰&否則不規則的行爲碎片會導致。
如果我需要一個特定的生命週期回調(onActivityResult)或者如果我被第三方庫(Android Pay,Braintree)強制執行,那麼我只能使用片段。
單獨通過接口
你的觀點這基本上是什麼MVP/MVVM模式是一回事。它將視圖與業務邏輯分開(Presenter/ViewModel)。這將幫助你,因爲你的活動/段將實現View接口:
public class MyActivity implements MyView { ...
當你的活動啓動時,它結合了演示,當它完成解除綁定:
protected void onCreate(Bundle bundle) {
// ...
presenter.bind(this);
}
protected void onDestroy() {
// ...
presenter.unbind(this);
}
現在,當您的企業邏輯異步操作完成並嘗試更新視圖,如果活動已完成視圖將被解除綁定。您可以將它檢查爲空或(如我所願)在它的位置有一個無操作視圖。
不更新查看從長時間運行的異步操作
如果可能不直接從一個長期運行的異步進程(網絡或重計算)的結果更新您的看法。而是將結果緩存在持久層(db/prefs/file)中。讓視圖然後訂閱持久層的數據。
訂閱可以通過多種方式完成 - RxJava,事件總線通知,靜態回調。
這種方式當結果回來它只是得到保存。如果視圖仍處於活動狀態,則會通知它並從持久性中加載結果。如果沒有,則可以在下次加載時從那裏接收它們。
最後
順便說一句,你可以調用.commitAllowingStateLoss()
,而不是僅僅.commit()
,它不會崩潰。這並不能真正解決潛在的問題,雖然...
在什麼情況下你'不能執行此操作後onSaveInstanceState'? – azizbekian
當我嘗試這樣做:fragmentTransaction.beginTransaction()。replace(R.id.my_frag_cont,fragment).commit(); – Alexei
查看此問題的答案。他們解釋了這個問題和可能的解決方案。 http://stackoverflow.com/questions/7469082/getting-exception-illegalstateexception-can-not-perform-this-action-after-onsa – Juan