2013-03-25 24 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处于后台堆栈中)之前进行初始化。