【发布时间】:2018-12-12 15:34:49
【问题描述】:
我遇到了崩溃,如果 android 操作系统杀死一个进程,当应用程序尝试从保存的实例中重建活动和片段时,我的 recyclerview 的适配器始终为空。
这是我的层次结构:
Parent Activity // destroyed when process is killed
Nested View Pager Fragment // view pager containing four recycler view fragments
Recycler Frag 1
Recycler Frag 2
Recycler Frag 3
Recycler Frag 4
这些回收器片段中的每一个都是完全相同的片段,除了当父活动创建它们的新实例时,我调用一个公开的 setter 方法来设置类型为 RecyclerView.Adapter 的适配器(原因是这些中的每一个frags 可能是一个分页回收器,但它显示的内容以及用户与之交互的方式可能会有所不同)来自父活动的示例代码:
RecyclerFrag feedFrag = RecyclerFrag.newInstance();
feedFrag.setAdapter(new myCustomAdapter());
现在,我的最终用户遇到了崩溃,如果他们将此活动置于后台,并且操作系统决定终止此活动所在的进程,则它无法正确恢复自身。据我所见,除了适配器为空外,一切都在恢复中。然后代码尝试访问适配器接口并与 NPE 一起崩溃。
我不知道为什么会这样。我还试图在此类事件中恢复活动和片段。我已经阅读了一堆关于状态恢复的帖子和文档,但仍然找不到解决方案。这是我尝试过的解决方案示例,也许有人可以指出我的逻辑中的缺陷/差距。
让回收器frag将自己存储在fragmentManager中,并尝试在onActivityCreated方法调用中读回它。
@Override
public void onSaveInstanceState(@NonNull Bundle outState) {
super.onSaveInstanceState(outState);
getFragmentManager().putFragment(outState, "myFrag", this);
...
}
然后:
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if(savedInstanceState != null) {
getFragmentManager().getFragment(savedInstanceState, "myFrag");
...
}
}
对我来说,这感觉就像我错过了标记。片段获取对自身的引用然后尝试从中设置自己是没有意义的。更糟糕的是,它返回的片段有一个空适配器。生活和学习。
接下来,我尝试保存在父活动中创建的片段以用于 viewPager 实现,然后尝试在父活动 onCreate 中恢复这些片段。父类如下所示:
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
getSupportFragmentManager().putFragment(outState, "frag1", frag1);
...
}
然后:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(savedInstanceState != null) {
getSupportFragmentManager.getFragment(savedInstanceState, "myFrag);
...
}
}
关于这种方法的有趣之处在于,当我在 onSaveInstance 方法中将片段保存到管理器时,我的 adpater 不为 null,这是有道理的。当我在 onCreate 方法中抓取它时,该片段适配器现在为空。
这让我有了最后的想法,也许恢复适配器效率不高,不应该这样做。再一次,在 Recycler Fragment 中创建适配器对我来说没有意义,因为我希望这个片段采用RecyclerView.Adapter 类型的任何适配器实现。对于进一步的上下文,viewPager 实现的类型是FragmentStatePagerAdapter,它提供了最简单的方法来覆盖 get it 运行。据我了解,这正是您应该做的,父 FragmentStatePagerAdapter 将为您处理其余的恢复过程。这个假设我错了吗?
我非常感谢您就此事提供任何意见。我试图提供尽可能多的信息,但是,如果您认为您可以在提供更多信息的情况下帮助我,如果您让我知道,我很乐意更新我的帖子。谢谢!
最终编辑: 我最终采用了与标记为这篇文章答案的解决方案类似的解决方案。我将在下面提供我的实际解决方案,以便将来有人发现这篇文章对他们的情况有帮助。
- 删除 Recycler Fragments 接口中的公共 setter 方法。鉴于我总是在初始化片段后立即调用 setter,因此这种方法存在问题并且在未来的开发人员必须在代码中工作时容易出错是有道理的。
- 创建枚举类型作为回收器中对象的数据抽象。鉴于某些隐含类型的数据需要不同的适配器,这似乎也是合适的。我的意思是我可能有一个汽车对象,但取决于我在用户旅程中所处的位置,汽车对象可能需要一个不同的适配器,这些适配器在
CAR_PREVIEW_SEARCH或CAR_PREVIEW_SELECTABLE等枚举中反映出来,这在@987654333 期间发挥作用@
【问题讨论】:
标签: android android-fragments android-recyclerview android-savedstate