onAttach()不调用setRetainInstance(真正的);onAttach、setRetainInstance

2023-09-07 12:17:41 作者:月亮男神

我有一个父片段拥有一个孩子的片段,以及两者的片段的 onAttach onCreateView 方法记录用于调试的目的。

I have a parent fragment that holds a single child fragment, and both of the fragment's onAttach and onCreateView methods are logged for debugging purposes.

在我父片段添加到活动中是这样的:

When I add the parent fragment to the Activity this way:

parent.setRetainInstance(false);

一旋转后的输出是这样的:

the output after a rotation is this:

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);

输出(旋转后)是这样的:

the output (after the rotation) is this:

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 )。此方案只是一个演示,其实我有调试一个复杂的应用程序,找出是什么原因导致的故障。该应用程序有内存问题,由于方向改变后,孩子的片段泄露了previous活动(作为一名听众在onAttach设置)。

To summarize, child fragment's onAttach method won't get called if the parent is a retained fragment (I assume neither onDetach). This scenario just a demo, I actually had to debug a complex application to find out what causes the failure. The application had memory issues, because after orientation change, the child fragment leaked the previous Activity (as a listener set in onAttach).

如果有人有相同的问题,解决方法可以是手动调用儿童 onAttach 从父片段的 onAttach

If someone has the same problem, a workaround could be to manually call the children's onAttach from the parent fragment's onAttach.

,问题是:这是一个错误

推荐答案

当你做一个setRetainInstance(真),该片段保留其配置(因此,其引用到嵌套的片段,这是从来没有真正分离/附后)。这可能发生,例如,一个configurationChange(如旋转)期间。

When you do a setRetainInstance(true), the fragment retains its configuration (and therefore its reference to the nested fragment, which is never really detached/attached). This can happen, for example, during a configurationChange (like a rotation).

因此​​,这不是一个错误,这是由Android的设计。

So this is not a bug, it's by Android's design.

要回答你的问题,你可以保持活动/监听器引用作为WeakReference的所以它得到,当它不再需要释放。

To answer your question, you could keep the Activity/Listener reference as a WeakReference so it gets released when it's no longer needed.

在另一方面,我会重新考虑整个想法,好像你应该​​有一个观察者模式在这里(订阅/时的onStop /的onPause或类似从侦听/观察者退订)。

On the other hand, I'd rethink the whole idea, seems like you should have an observer pattern here (subscribe/unsubscribe from the listener/observer during onStop/onPause or similar).

注意:没有变得更好,我讨厌Android的生命周期方法

note: that doesn't make it better, I loathe Android's lifecycle methods