【问题标题】:Why caching inflated layout in a static variable could be a memory leak?为什么在静态变量中缓存膨胀的布局可能是内存泄漏?
【发布时间】:2012-07-31 08:30:59
【问题描述】:

我需要预先加载一个复杂的布局,以便我可以在第一次更快地显示活动:

LayoutInflater inflater = (LayoutInflater) mainActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

SlowActivity.cachedView = inflater.inflate(R.layout.activity_layout, null, false);

SlowActivity 开始时...

public static View cachedView = null; 

@Override
public void onCreate(Bundle savedInstanceState) {

  super.onCreate(savedInstanceState);
        setContentView(this.cachedView);
      }
}

我找不到我在哪里读到它,但有人说我正在使用 stati 变量来存储膨胀的布局进行内存泄漏。

为什么?

也许我需要在活动被销毁时释放一些资源(从不,它总是放在后台......)

【问题讨论】:

    标签: android layout layout-inflater


    【解决方案1】:

    这是因为布局,就像所有视图一样,有一个对持有它的活动的引用。

    因此,在 Activity 关闭并应该被释放后,静态变量持有对引用 this Activity 的视图的引用,因此应用程序占用的内存超出了应有的范围。

    视图不是您应该尽量避免使用静态变量进行缓存的唯一变量。一个例子是 drawables ,如 here 所示。

    【讨论】:

    • 幸运的是,我只在其中使用了静态变量来加快完整的布局加载(1-2 秒)。可以强制GC释放静态变量占用的内存吗?
    • 你不能强迫,你可以给它一个线索,现在是时候了,使用 System.gc() 。当然,避免内存泄漏的最小方法是将引用设置为 null。如果不确定何时设置 null ,也可以使用 weakReference 或 softReference ,但需要小心。
    • 好的,对我来说已经足够了,在继续之前我需要更多关于“内存泄漏”的知识。谢谢。
    • 你也可以观看这个视频:google.com/events/io/2011/sessions/…,请注意,在任何情况下,缓存视图都是有问题的(尤其是对于所有扩展 adapterView 的类,请查看“listView 的世界” " 视频 了解 更多 信息 ) , 所以 如果 你 选择 做 , 请 小心 做 .
    【解决方案2】:

    因为 Android 可以(并且将会)在每次需要内存时销毁您的应用程序/活动(包括静态变量!)。所以你必须考虑一下,什么时候创建静态变量。否则,在应用程序处于非活动状态后,您会变得奇怪且难以发现崩溃。

    【讨论】:

    • 所以如果我发现静态变量为空,我可以正常加载布局:if (cachedView != null) { setContentView(cachedView); } else { setContentView(R.layout.activity_layout); }
    • ...但是如何强制 GC 释放静态布局变量?
    • 对不起,我没有深入了解 java 来告诉您对 GC 的更深入了解。但是您的解决方案应该有效。我也是这样做的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多