2013-03-25 36 views
21

我有碎片我保留在FragmentManager的後臺。每一個片段狀態保存與成員變量方位的變化,像這樣的例子:在堆棧中使用onSaveInstanceState和fragment?

@Override 
public void onSaveInstanceState(Bundle outState) 
{ 
    super.onSaveInstanceState(outState); 
    outState.putLong("userId", mUserId); 
    outState.putString("username", mUsername); 
} 

我的問題是,如果有一個方向的變化,因爲在堆棧中的每個片段被通過的onSaveInstanceState叫,我得到一個空指針異常,因爲成員變量不再存在。

關於如何解決這個問題的任何想法?

+0

你能提供你的logcat錯誤信息嗎? – 2013-04-08 07:31:31

+0

onSaveInstanceState在應用實際更改之前被調用,所以當您調用它們時,您的變量應該存在,除非它們由於代碼中的其他錯誤而爲空。發佈一些更多的代碼以及Logcat的錯誤輸出形式。 – Shade 2013-04-10 12:09:34

+0

我可以向你保證我的變數是好的。我認爲問題在於,我們在後臺堆棧中的碎片在拆卸時並沒有進入保存狀態狀態, onSaveInstanceState只在活動被銷燬時調用,但我的變量不再存在。所以我目前的解決方案是:「if(mUserId!= null && mUsername!= null)...」。這並不美觀,但它解決了這個問題。如果片段被拆除時沒有調用片段,我覺得有一個片段的onSaveInstanceState方法很奇怪。 – 2013-04-10 16:07:28

回答

34

您的成員變量可能不再存在,因爲Activity中的FragmentManager正在與您的所有片段一起死亡。

您需要覆蓋Activity類的方法onSaveInstanceState,因爲在保存Fragments狀態之前需要保存Activity狀態。

正如documentation說:

有很多情況下片段可以被大部分拆毀(當放在後面堆棧上沒有UI表現,如),但它的狀態不會被保存,直到其擁有的活動實際上需要保存其狀態。

UPDATE

在你ActivityonSaveInstanceStateonRestoreInstanceState,儘量節省您Fragment引用,然後用這樣的還原出來:

public void onSaveInstanceState(Bundle outState){ 
    getFragmentManager().putFragment(outState,"myfragment",myfragment); 
} 
public void onRestoreInstanceState(Bundle inState){ 
    myFragment = getFragmentManager().getFragment(inState,"myfragment"); 
} 

告訴我,然後,如果你的運氣! :-)

+0

那我該怎麼辦?我應該從activity的onSaveInstanceState中調用片段的onSaveInstanceState嗎? – 2013-04-10 01:53:23

+0

答案中的一個更新。 – 2013-04-10 17:04:54

+0

ok ... so onSaveInstanceState for fragments是非常沒有價值的。至少,對於位於後端堆棧中的碎片(碎片事務)。 – 2013-04-10 17:43:17

0

是否在片段幫助上設置了setRetainInstance。 嘗試

+0

如果fragment用於UI目的,那麼永遠不要將'setRetainInstance'設置爲'true'! – matusalem 2016-09-21 09:33:51

5

大廈豪爾赫·吉爾 - 「xɔɾ.xɛXIL答案 注意以下幾點:

  • 不要忘記的onSaveInstanceState叫() 和onRestoreInstanceState的超級實現()。
  • 如果您使用的是支持包:請使用getSupportFragmentManager()而不是getFragmentManager()。
  • 當你檢索你的原始片段時,你必須施放它。

對不起,上尉明顯!

0

我認爲正確的解決方案是讀取onCreate中的savedInstanceState中的那些成員變量,這似乎總是在onSaveInstanceState之前被調用。如果您處理onViewCreated中的字段,則他們沒有機會在下一個onSaveInstanceState(在這種特殊情況下,當Fragment處於後臺堆棧中)之前進行初始化。