【问题标题】:Using onSaveInstanceState with fragments in backstack?将 onSaveInstanceState 与 backstack 中的片段一起使用?
【发布时间】:2013-03-25 06:12:25
【问题描述】:

我有片段保存在 FragmentManager 的后台堆栈中。保存每个片段状态以使用成员变量更改方向,例如:

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

我的问题是,如果方向发生变化,由于 backstack 中的每个片段都通过 onSaveInstanceState 调用,我得到一个空指针异常,因为成员变量不再存在。

关于如何解决这个问题的任何想法?

【问题讨论】:

  • 你能提供你的 logcat 错误信息吗?
  • onSaveInstanceState 在应用实际更改之前被调用,所以当你调用它们时你的变量应该存在,除非它们因为代码中的其他错误而为空。发布更多代码以及错误输出表单 Logcat。
  • 我可以向您保证,我的变量没问题。我认为问题在于我在后台堆栈中的片段在被拆除时没有被调用 onSaveInstanceState; onSaveInstanceState 仅在活动被销毁时调用,但我的变量不再存在。所以我目前的解决方案是:“if (mUserId != null && mUsername != null) ...”。它不漂亮,但它解决了问题。如果在片段被拆除时没有调用它,我觉得有一个片段的 onSaveInstanceState 方法很奇怪。

标签: android android-fragments


【解决方案1】:

您的成员变量可能不再存在,因为您的 Activity 中的 FragmentManager 与您的所有片段一起死亡。

您还需要覆盖 Activity 类的方法 onSaveInstanceState,因为您需要先保存 Activity 状态,然后再保存 Fragments 状态。

正如documentation 所说:

在很多情况下,一个片段可能大部分被拆除(例如当放置在没有显示 UI 的后堆栈上时),但它的状态不会被保存,直到它拥有的 Activity 实际需要保存它的状态。

更新

在您的 Activity onSaveInstanceStateonRestoreInstanceState 中,尝试保存您的 Fragment 引用,然后使用以下内容恢复它们:

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

如果你运气好,请告诉我! :-)

【讨论】:

  • 那我该怎么办?我应该从 Activity 的 onSaveInstanceState 中调用片段的 onSaveInstanceState 吗?
  • 答案中的更新。
  • ok...所以片段的 onSaveInstanceState 几乎毫无价值。至少,对于在后台堆栈中的片段(片段事务)。
  • 是的,事实上,我认为您可以根据您的案件性质退出onSaveInstanceState
  • @Jorge Gil 如果您从片段中点击主页按钮,并且在您尝试打开一段时间后,我们如何才能恢复相同的状态。如果操作系统在两者之间调用了 GC。
【解决方案2】:

以 Jorge Gil 为基础 - 'xɔɾ.xɛ xil 答案 请注意以下几点:

  • 不要忘记调用 onSaveInstanceState() 的超级实现 和 onRestoreInstanceState()。
  • 如果您使用的是支持包:请使用 getSupportFragmentManager() 而不是 getFragmentManager()。
  • 在检索原始片段时,您必须投射它。

很抱歉很明显是队长!

【讨论】:

    【解决方案3】:

    是否在片段帮助上设置 setRetainInstance。 试试看

    【讨论】:

    • 如果片段用于 UI 目的,那么永远不要将setRetainInstance 改为true
    【解决方案4】:

    我认为正确的解决方案是从onCreate 中的savedInstanceState 中读取这些成员变量,这似乎总是在onSaveInstanceState 之前调用。如果您处理onViewCreated 中的字段,则它们没有机会在下一个onSaveInstanceState 之前被初始化(在这种特殊情况下,当Fragment 在后台堆栈中时)。

    【讨论】:

      猜你喜欢
      • 2012-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多