保留片段,用户界面和内存泄漏 [英] Retained Fragments with UI and memory leaks
问题描述
我读过的片段presenting UI设置 .setOnRetainInstance(真)
可能会导致内存泄漏。
I've read that setting .setOnRetainInstance(true)
on fragments presenting UI may lead to memory leaks.
可能有人请解释为何以及如何会发生这种情况?我没有找到一个详细的解释的任何地方。
Could somebody please explain why and how this would happen? I didn't find a detailed explanation anywhere.
推荐答案
在片段
与UI你常常省下一些查看
取值为实例状态,以加快进入。例如,一个链接到你的的EditText
,所以你不必 findViewById
这一切的时候。
In a Fragment
with UI you often save some View
s as instance state to speed up access. For example a link to your EditText
so you don't have to findViewById
it all the time.
现在的问题是,一个查看
有一个参考的活动
上下文。现在,如果你保留了查看
还保留提及这方面。
The problem is that a View
keeps a reference to the Activity
context. Now if you retain a View
you also retain a reference to that context.
这是没有问题的上下文是否仍然有效,但典型的保留情况下重新启动活动。很多时候,一个屏幕旋转的例子。活动娱乐将创建一个新的上下文老上下文意在垃圾收集。但它不能被现在的垃圾收集,因为你的片段
仍具有参考旧的。
That is no problem if the context is still valid but the typical retain case is restarting the Activity. Very often for a screen rotation for example. Activity recreation will create a new context and old contexts are intended to be garbage collected. But it can't be garbage collected now since your Fragment
still has a reference to the old one.
下面的示例演示如何不去做
Following example shows how not to do it
public class LeakyFragment extends Fragment {
private View mLeak; // retained
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mLeak = inflater.inflate(R.layout.whatever, container, false);
return mLeak;
}
@Override
public void onDestroyView() {
super.onDestroyView();
// not cleaning up.
}
}
要摆脱这个问题,你需要清除 onDestroyView
来你的用户界面的所有引用。一旦片段
实例被重新使用,你会被要求创建 onCreateView
全新的UI。还有在保持UI后 onDestroyView
没有任何意义。用户界面是不会被使用。
To get rid of that problem, you need to clear all references to your UI in onDestroyView
. Once the Fragment
instance is re-used you will be asked to create a new UI on onCreateView
. There is also no point in keeping the UI after onDestroyView
. The Ui is not going to be used.
在这个例子中的修复才刚刚改变 onDestroyView
到
The fix in this example is just changing onDestroyView
to
@Override
public void onDestroyView() {
super.onDestroyView();
mLeak = null; // now cleaning up!
}
和除了保持引用查看
是你应该很明显跟不上从<$提到了活动
(例如: C $ C> onAttach - 干净的 onDetach
)或上下文
(除非它是应用程序
上下文)。
And besides keeping references to View
s you should obviously not keep references to the Activity
(e.g. from onAttach
- clean on onDetach
) or any Context
(unless it's the Application
context).
这篇关于保留片段,用户界面和内存泄漏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!