【问题标题】:Full managing of fragments flow in Android全面管理 Android 中的 Fragment 流
【发布时间】:2023-03-18 04:11:01
【问题描述】:

我的应用程序中有一个特殊的片段流,因此我需要能够切换到任何片段,同时尽可能将片段保留在内存中(所以如果内存紧张,可以释放片段) .

到目前为止,我已经成功地替换了当前片段,但问题是前一个片段总是被破坏,所以如果我回到它(例如使用操作栏),它会重新-创建,这需要一些时间。

我使用片段而不是活动的原因是操作栏的良好使用、将多个片段放在同一个容器中的能力、不灵活的活动意图使用等等......

我不使用“返回”堆栈的原因是我希望从任何片段转到任何片段,因为流程可以改变。

这是我的代码的 sn-p:

Fragment fragment=... ; //get the fragment from cache or create if not available yet...
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
        ft.replace(R.id.mainActivity_fragmentContainer, fragment).commit();

我也尝试过使用 ViewPager,但由于我不想具有滑动效果(它允许您滑动到其他片段)并且由于其中一个片段已经包含 viewPager,所以它是一个障碍。在主 viewPager 上禁用滑动效果会以某种方式在另一个上禁用它。

顺便说一句,我正在为片段使用 android 支持库,而不是原生 API。

我的问题是: 我怎样才能完全控制要转到哪个片段,同时最大限度地提高速度并避免片段使用过多的内存?


编辑: 现在,我使用下一个解决方法: 对于 onDestroyView ,我采用创建视图的父级并从那里删除创建的视图。

对于 onCreateView ,如果我已经拥有之前创建的视图,我会返回它。

然而,我认为这是一件非常冒险的事情,因为我不确定片段管理是如何工作的,所以它可能会导致奇怪的问题。另外,我不确定如果 android 确定它的内存不足会发生什么 - 它会破坏未使用的片段(这很好)还是会导致内存不足异常(这很糟糕)。

【问题讨论】:

  • 你的问题在哪里?我们能帮你什么吗?是关于创建片段时的延迟吗?您是否检查了显示片段所需的基础数据创建?

标签: android android-activity transactions fragment flow


【解决方案1】:

我同意您关于“风险很大”的评论。由于您的方法的后果不是很清楚,因此我不建议使用此方法。

为了更好地了解您的问题并给您一些提示:

  1. 您认为什么是慢?我也一直“疯狂”地切换片段,它在平板电脑上运行良好,但在一些低端手机上需要更长的时间 - 但仍然可以接受

  2. 您的片段需要创建多少工作?即每次需要准备什么样的底层数据? (再一次,我有几个超过 1k 条目的列表片段,它们每次都准备好,而且速度很快)

  3. 如何精确替换片段?特别是你打电话给getFragmentManager().executePendingTransactions();

【讨论】:

  • 1.速度不是主要问题。主要问题是灵活性 - 转到我需要的任何片段,而无需在可能的情况下重新创建它。 2.好吧,有些片段需要在其中有一个webview,不应该刷新而只能恢复,有些有ViewPager。 3.已经写在sn-p里了。
  • 关于记忆的问题似乎并不是一个碎片问题,因为碎片不需要特别强烈的记忆——afaik 它甚至比活动还要少。一般来说,这似乎更像是一个记忆问题?对?然后,您需要更具体地说明您想要做什么以及为什么您认为它需要大量内存。顺便说一句,为了增加任何内存被“直接访问”的机会,你需要对它们进行引用,引用越多,你请求的频率越高,它们被保存在快速访问存储中的概率就越高
  • 再次,请阅读我提出的问题。主要问题是灵活性 - 如何从任何片段转到任何片段而不重新创建它,另一个问题是解决方案是否会在应用程序占用太多内存时释放片段,这样我就不会用尽- 内存异常很容易。
  • 您是否对它真正需要多少内存进行了内存分析。我目前正在开发一个应用程序,该应用程序在几个片段中具有相当重的位图。我所要做的就是确保我使用的任何内存都能快速回收。例如,片段需要大约 10-20MB 的数据,并且在跳转时都被回收和重新创建。没有任何问题。如果您真的对此感到担忧,请存储基础数据并重新使用它。遇到问题并完成分析后,为什么不进行优化?
  • 您是否已经检查过片段的分离和附加方法...
【解决方案2】:

实现目标的一种方法是使用 FragmentTransaction.show 和 FragmentTransaction.hide。您可以使用 Fragment.isAdded 来确定是第一次显示还是调用 FragmentTranscation.add。缺点是当显示和隐藏片段时你不会得到暂停/恢复事件;您将需要覆盖 onHiddenChanged。如果您想支持后退导航,您还必须管理自己的堆栈。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-13
    • 2015-10-26
    • 2014-06-07
    • 2023-04-09
    • 2021-03-14
    • 2016-01-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多