onAttach()没有用setRetainInstance(true)调用;

时间:2014-07-08 18:33:07

标签: android android-fragments

我有一个包含单个子片段的父片段,并且记录了片段的onAttachonCreateView方法以进行调试。

当我以这种方式将父片段添加到Activity时:

parent.setRetainInstance(false);

旋转后的输出是:

07-08 20:10:52.295: E/TAG(14216): Parent's onAttach called!
07-08 20:10:52.295: E/TAG(14216): Parent's onCreateView called!
07-08 20:10:52.305: E/TAG(14216): Child's onAttach called!
07-08 20:10:52.305: E/TAG(14216): Child's onCreateView called!

但保留:

parent.setRetainInstance(true);

输出(旋转后)是:

07-08 20:10:55.395: E/TAG(14216): Parent's onAttach called!
07-08 20:10:55.395: E/TAG(14216): Parent's onCreateView called!
07-08 20:10:55.400: E/TAG(14216): Child's onCreateView called!

总而言之,如果父级是保留的片段(我不假设onAttach),则子片段的onDetach方法不会被调用。这个场景只是一个演示,我实际上不得不调试一个复杂的应用程序来找出导致失败的原因。应用程序存在内存问题,因为在方向更改后,子片段泄露了上一个Activity(作为onAttach中的侦听器集)。

如果有人遇到同样的问题,解决方法可能是从父片段的onAttach手动调用孩子的onAttach

问题是:这是一个错误吗?

1 个答案:

答案 0 :(得分:2)

当你执行setRetainInstance(true)时,片段会保留其配置(因此它对嵌套片段的引用,它永远不会真正分离/附加)。例如,在configurationChange(如旋转)期间可能会发生这种情况。

所以这不是一个bug,而是Android的设计。

要回答您的问题,您可以将活动/监听器引用保留为WeakReference,以便在不再需要时将其释放。

另一方面,我重新考虑整个想法,看起来你应该有一个观察者模式(在onStop / onPause或类似期间订阅/取消订阅监听器/观察者)。

注意:不会让它变得更好,我厌恶Android的生命周期方法