【问题标题】:android:support:fragments saved by Activity is getting larger and causing TransactionTooLargeExceptionActivity 保存的 android:support:fragments 越来越大,导致 TransactionTooLargeException
【发布时间】:2019-12-26 08:10:42
【问题描述】:

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

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

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

我使用TooLargeTool 来跟踪问题的来源,我发现当我在活动中的片段之间切换时,SaveInstanceState 中有一个android:support:fragments 键,它变得越来越大(以指数方式)直到崩溃发生。

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

按照建议 here 删除它会导致 Activity 在被操作系统杀死后无法正常恢复。

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

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

谢谢!

【问题讨论】:

标签: android android-fragments android-activity onsaveinstancestate transactiontoolargeexception


【解决方案1】:

我在我的 Activity 中通过 supportFragmentManager.registerFragmentLifecycleCallbacks 进行了一些调试,覆盖并在 onFragmentSaveInstanceState 中设置断点。

看来android:support:fragments Bundle 包含

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-02
    • 1970-01-01
    • 2017-01-28
    • 2017-10-15
    • 2019-07-01
    • 2019-01-04
    • 1970-01-01
    相关资源
    最近更新 更多