【问题标题】:Fragments not destroyed when recreate() activityrecreate() 活动时片段未销毁
【发布时间】:2014-11-10 17:54:59
【问题描述】:

我有一个发送网络调用的支持库片段,当它收到特定的网络响应时,recreate() 是父活动。我可以看到该活动确实被重新创建,因为我可以看到 onCreate()onDestroy() 被调用。

但是在重新创建活动之后,片段仍然存在并且它陷入了不断重新创建和制作新片段的循环中。

这是活动的onCreate() 的一部分:

    if (someLogic()) {
        fragmentA = new FragmentA();
        FragmentUtil.addFragment(getSupportFragmentManager(), fragmentA);
    } else {
        fragmentB = new FragmentB();
        FragmentUtil.addFragment(getSupportFragmentManager(), fragmentB);
    }

FragmentA 是进行网络调用的片段,FragmentB 是应该在recreate() 之后显示的片段。当我使用getSupportFragmentManager().getFragments() 检查片段列表时,我看到了 1 个 FragmentA 实例和 16 个 FragmentB 实例。

我的问题是为什么会发生这种情况,我该如何解决?

【问题讨论】:

  • 你能展示你如何添加片段和重新创建活动吗?我的猜测是您必须在重新启动活动之前删除 fragmentA,但我需要查看代码。顺便说一句,您为什么不简单地将 fragmentA 替换为 fragmentB 而不是重新启动活动?
  • 并不是说它是一个具体的答案或它是理想的解决方案,但您可以检查您的片段堆栈并仅在需要时添加一个新片段,否则/或者您可以替换/刷新当前片段

标签: android android-fragments


【解决方案1】:

调用recreate() 实质上会导致Activity 进行配置更改。配置更改会导致 Activity 及其 Fragments 被销毁并重新创建。因此,当这种情况发生时,您的 Fragments 实际上应该被销毁(您可以通过在片段的 onDestroy 方法中添加 Log 消息来亲自查看)。

配置更改会导致片段被销毁和创建,但是并不意味着FragmentManager 将简单地忘记曾经存在的片段。配置更改发生后,FragmentManager 仍将持有对新创建的片段的引用。

您可以做的一件事是在您的活动的onCreate() 中执行类似的操作来防止创建多个片段:

if (savedInstanceState == null) {
    // The Activity is being created for the first time, so create and
    // add new fragments.
} else {
    // Otherwise, the activity is coming back after being destroyed.
    // The FragmentManager will restore the old Fragments so we don't
    // need to create any new ones here.
}

【讨论】:

  • 无论如何在游戏过程中明确不保留片段?我有一个日/夜模式布局设置,我在内存中有多个片段副本存在一些问题
  • @spy 您可以在重新创建 Activity 之前手动删除片段,“mFragmentManager.beginTransaction().remove(mFragment).commit();”。
【解决方案2】:

我遇到了与@spy 所写相同的情况,在更改日/夜模式后重新创建ActivityActivity 有四个Fragments,在调用Activity.recreate() 后,它们会恢复,因为FragmentManager 将它们保存为@Alex Lockwood 所述。但是由于项目的一些架构原因,在娱乐后恢复而不添加Fragments对我没有帮助,我希望它们消失。

解决方案是在调用 Activity.recreate() 之前从 FragmentManager 中删除 Fragments,在我的情况下是在 Activity.onStart() 中:

FragmentManager fragmentManager = getSupportFragmentManager();
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();

Fragment fragmentA = fragmentManager.findFragmentByTag("fragmentATag");
if(fragmentA != null) 
    fragmentTransaction.remove(fragment);
// Find and delete other Fragments

fragmentTransaction.commit(); // or commitAllowingStateLoss()

recreate();

这样,当调用Activity.onCreate() 时,您将不会恢复Fragments

【讨论】:

  • 另一种选择是在创建活动时调用super.onCreate(null);,但是,我不确定它可能还有什么其他缺点
猜你喜欢
  • 2022-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多