带有 UI 和内存泄漏的保留片段

2024-01-12

我读过那个设置.setOnRetainInstance(true)在呈现 UI 的片段上可能会导致内存泄漏。

有人可以解释一下为什么会发生这种情况以及如何发生吗?我在任何地方都没有找到详细的解释。


In a Fragment使用 UI 通常可以节省一些Views 作为实例状态以加速访问。例如,链接到您的EditText所以你不必findViewById一直都是这样。

问题是一个View保留对Activity语境。现在,如果您保留View您还保留对该上下文的引用。

如果上下文仍然有效,但典型的保留情况是重新启动活动,那么这没有问题。例如,经常用于屏幕旋转。活动重新创建将创建一个新的上下文,而旧的上下文将被垃圾收集。但它现在不能被垃圾收集,因为你Fragment仍然有对旧版本的引用。

下面的例子展示了如何不这样做

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.
    }
}

要解决这个问题,您需要清除对 UI 的所有引用onDestroyView。一旦Fragment实例被重新使用,您将被要求创建一个新的 UIonCreateView。之后保留 UI 也没有意义onDestroyView。不会使用 Ui。

本例中的修复只是改变onDestroyView to

@Override
public void onDestroyView() {
    super.onDestroyView();
    mLeak = null; // now cleaning up!
}

除了保留参考文献之外View你显然不应该保留对Activity(例如来自onAttach- 清洁上onDetach)或任何Context(除非它是Application语境)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

带有 UI 和内存泄漏的保留片段 的相关文章

随机推荐