【问题标题】:Restoring Fragment Instance with references使用引用恢复片段实例
【发布时间】:2013-01-30 02:01:55
【问题描述】:

短版:我想知道当片段包含对无法序列化或复制的对象的引用并且需要留在记忆中。

加长版: 在我的应用程序中,我使用连接到自定义 FragmentPagerAdapterViewPager,该 FragmentPagerAdapter 实例化了许多片段,这些片段显示 ListView 中包含的数据(计划)。所有这些都包含在父片段中。当由适配器实例化时,每个页面片段都被传递一个对一个对象(“ScheduleManager”)的引用,该对象执行以下几项操作:

  • 包含要显示的数据
  • 持有对 Context 对象的引用(以便访问 SharedPreferences
  • 持有对父片段 LoaderManager 的引用,以便它可以重新加载数据
  • 实现 OnClick- 和 ActionMode 回调监听器(以便能够创建和处理适用于所有页面的操作模式;页面片段将对象作为监听器添加到他们的列表视图)
  • 定义一个回调接口来通知监听器状态变化或数据何时重新加载(页面片段将自己注册为监听器)。

基本上,ScheduleManager 将所有内容放在一起,并实现了我的应用程序的这个(“调度”)部分的主要逻辑,即加载和提供数据,以及通过以下方式修改和重新加载数据的方法动作模式。不知道这样设计好不好……

我的问题是在这些情况下我应该如何恢复 Fragments 实例状态?我无法将 ScheduleManager 序列化为一个包,因为它会丢失对 Context 和 LoaderManager 的引用(当然,我会使用 setArguments / getArguments)。此外,所有页面片段必须引用相同的 ScheduleManager 实例,否则共享操作模式将不起作用。除此之外,我不想在每次恢复片段时都复制整个计划数据。我想将此对象保留在内存中,并让页面片段在恢复时回收对它的引用。

我想我可以让包含的活动持有 ScheduleManager 并让 PageFragment 查询它以获取参考。但如果可能的话,我更愿意将父片段中的所有内容保持为独立和模块化(不同的项目可以有不同的时间表)。在写这篇文章的时候,虽然我觉得没有办法解决这个问题。

当然,在重新创建父片段时,它也可以重新创建 ScheduleManager 并向其提供所需的引用(Context + LoaderManager)。问题是父片段的每个实例不能有多个ScheduleManager实例,那么如何让嵌套的页面片段重新连接到它。

【问题讨论】:

  • 考虑将引用作为静态存储在 Activity 中,然后使用 onAttach(Activity) 来恢复这些。感觉很杂乱,所以我希望看到更好的答案。
  • 感谢您的评论!就像我在评论中所写的那样,我希望将 Activity 排除在外。静态成员将是一种解决方案(无需将它们放在活动中,可以是片段的一部分)。您可以添加一个静态集合(例如地图),然后将引用存储在其中以针对每个片段实例唯一的键。
  • 恕我直言,api 应该提供一些功能,以便它成为单线。

标签: android android-fragments restore


【解决方案1】:

这是我最终做的:

public void onCreate(Bundle savedInstanceState)
{
    Fragment fragment = this.getActivity().getFragmentManager().findFragmentByTag("SCHEDULE");
    if (fragment instanceof ScheduleMasterFragment)
    {
        ScheduleMasterFragment master = (ScheduleMasterFragment) fragment;
        this.scheduleManager = master.getScheduleManager();
    }
    else
    {
        throw new RuntimeException("SchedulePageFragment must be " +
                "the child of a ScheduleMasterFragment with Tag set to 'schedule'");
    }
    super.onCreate(savedInstanceState);
}

ScheduleManager 是我想要保留的参考。至少这样我将所有代码保留在片段本身中,除了ScheduleMasterFragment 中的getScheduleManager,这是有道理的,因为ScheduleMasterFragment 不知何故是ScheduleManager 实例的所有者。

仍然欢迎任何更好的解决方案...

【讨论】:

    猜你喜欢
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多