保留片段,用户界面​​和内存泄漏 [英] Retained Fragments with UI and memory leaks

查看:97
本文介绍了保留片段,用户界面​​和内存泄漏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我读过的片段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 Views 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 Views 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆