11

我有一个控制几个片段的活动。默认片段是HomepageFragment. 当替换到不同的 Fragment 时,我总是确保堆栈保持平坦 - 这意味着只有HomepageFragment堆栈中的停留和当前的 Fragment 位于其顶部。例如:

  1. 活动打开HomepageFragment
  2. 需要替换为FragmentA- 一切都是好的原因HomepageFragment是最后一个片段
  3. 现在堆栈是HomepageFragment->FragmentA
  4. 需要替换为FragmentB- 首先弹出堆栈上的最后一个片段 ( fragmentA),而不是替换为FragmentB
  5. 现在堆栈是HomepageFragment->FragmentB

在生产中,我看到很多TransactionTooLargeException崩溃。

我曾经TooLargeTool跟踪问题的出处,我发现当我在活动中的片段之间切换时,有一个android:support:fragmentsSaveInstanceState变得越来越大(以指数方式),直到崩溃发生。

似乎即使从堆栈中弹出,有关原始事务的一些数据也会继续保存。

按照此处的建议将其删除会导致 Activity 在被操作系统杀死后无法正常恢复。

我的压平堆栈的方法有问题吗?有更好的方法吗?到底保存了哪些数据android:support:fragments

注意:我没有为这些片段设置任何参数。此外,他们在他们的 saveInstanceState 包中保存了非常小的数据。

谢谢!

4

1 回答 1

0

supportFragmentManager.registerFragmentLifecycleCallbacks在我的 Activity 中进行了一些调试,覆盖并在onFragmentSaveInstanceState.

所以似乎android:support:fragmentsBundle 包括

  1. 从 ViewModel 中保存的状态 (SavedStateHandle)
  2. 后栈中 Fragments 的导航参数

在我的例子中,罪魁祸首是一个自定义的 Parcelable,它可以增长到数百 kB。在后台堆栈和 SavedStateHandles 中有多个应用程序将超过 1MB 阈值并崩溃。

我通过仅传递该 Parcelable 的 ID 并从我的存储库中加载它来解决问题。性能略有下降,但不再崩溃。

于 2021-04-19T11:55:38.727 回答