java - Android - 使用图像资源背景动态构建 UI 时发生内存泄漏

标签 java android memory-management memory-leaks virtual-machine

我发誓有一个 Activity 正在泄漏内存。我正在开发的应用程序对图像做了很多处理,因此在直接使用位图时我不得不非常吝啬内存。我添加了一个 Activity,现在如果您使用这个新的 Activity,它基本上会使我超出内存使用的边缘,我最终会抛出“位图超出 VM 预算”异常。如果您从未启动此 Activity,一切都会像以前一样顺利。

我开始阅读有关内存泄漏的内容,我认为我遇到的情况与 Android 文档中的文章中描述的情况类似。我正在动态创建一堆 ImageView 并从资源中添加一个 BackgroundDrawable 并添加一个 OnClickListener。我想当 Activity 在其生命周期中遇到 onPause 时我必须做一些清理,但我想具体知道什么是正确的方法。

这是应该演示我正在使用的对象的代码...

    LinearLayout templateContainer;
    .
    .
    .
    ImageView imgTemplatePreview = (ImageView) item.findViewById(R.id.imgTemplatePreview);
    .
    .
    .
    imgTemplatePreview.setBackgroundDrawable(getResources().getDrawable(previewId));
    imgTemplatePreview.setOnClickListener(imgClick);
    templateContainer.addView(item); 

最佳答案

丰富,

如果您要处理那么多 Bitmap,您应该在不需要时主动清理它们(onPause 是一个好的开始)。

我记得很久以前关于 ImageView 及其奇怪行为的讨论,以及对它们显示的位图的挥之不去的引用。据我所知,如果您要使布局保持 Activity 状态但又不想泄漏,则应该从 ImageView 中删除对当前上下文的所有引用。删除 onClick 监听器和位图。如果您想主动释放内存,请在 Bitmap 上调用 .recycle()。确保您没有任何静态字段对上下文或对它的内部类引用有挥之不去的引用。

在此期间还提到了 Android 启动器的代码,作为他们执行其中一些操作的良好引用。开源是您的 friend 。

编辑

找到 Romain Guys 文章。基本上他提到了这一部分

This example is one of the simplest cases of leaking the Context and you can see how we worked around it in the Home screen’s source code (look for the unbindDrawables() method) by setting the stored drawables’ callbacks to null when the activity is destroyed.

现在我(还)从来没有管理过这种类型的内存使用,所以我建议从这里开始查看 The Home Screen Source更多细节。您会在第 620 行找到他们的 unbind() 方法

关于java - Android - 使用图像资源背景动态构建 UI 时发生内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4651366/

相关文章:

java - 没有已知的包错误。安卓5.0

java - 控制 ManagedExecutorServices/Java EE 7 的线程数

java - 如何将两个参数传递给命令行?

java - JNI , 调用 boolean 方法

android - 从listview android中删除了错误的行

c - 如何避免 realloc 溢出?

java - Reduce Integer.min 不返回最低元素

javascript - Java Socket 和 JS WebSocket

c# - .NET 中集合的内存分配

Lua元表对象无法从内存中清除?