android - java.lang.OutOfMemory错误: bitmap size exceeds VM budget - Android

标签 android memory memory-leaks bitmap out-of-memory

我在 Android 上开发了一个使用大量图像的应用程序。

应用程序运行一次,填充屏幕上的信息(LayoutsListviewsTextviewsImageViews等),用户读取信息。

没有动画,没有特效或者任何可以填满内存的东西。 有时绘图可能会改变。有些是android资源,有些是保存在SDCARD文件夹中的文件。

然后用户退出(执行 onDestroy 方法,并且应用程序由虚拟机保留在内存中),然后在某个时刻用户再次进入。

每次用户进入应用程序时,我都可以看到内存越来越多,直到用户收到 java.lang.OutOfMemoryError

那么处理许多图像的最佳/正确方法是什么?

我应该将它们放在静态方法中,这样它们就不会一直加载吗? 我是否必须以特殊方式清理布局或布局中使用的图像?

最佳答案

我发现开发 Android 应用程序时最常见的错误之一是“java.lang.OutOfMemoryError:位图大小超出 VM 预算”错误。在更改方向后,我经常在使用大量位图的 Activity 中发现此错误: Activity 被销毁,再次创建,并且布局因消耗可用于位图的 VM 内存的 XML 而“膨胀”。

垃圾收集器未正确取消分配先前 Activity 布局上的位图,因为它们交叉引用了其 Activity 。经过多次实验,我找到了一个很好的解决这个问题的方法。

首先,在 XML 布局的父 View 上设置“id”属性:

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="fill_parent"
     android:layout_height="fill_parent"
     android:id="@+id/RootView"
     >
     ...

然后,在 Activity 的 onDestroy() 方法上,调用 unbindDrawables() 方法,传递对父 View 的引用,然后执行 System .gc().

    @Override
    protected void onDestroy() {
    super.onDestroy();

    unbindDrawables(findViewById(R.id.RootView));
    System.gc();
    }

    private void unbindDrawables(View view) {
        if (view.getBackground() != null) {
        view.getBackground().setCallback(null);
        }
        if (view instanceof ViewGroup) {
            for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            unbindDrawables(((ViewGroup) view).getChildAt(i));
            }
        ((ViewGroup) view).removeAllViews();
        }
    }

这个unbindDrawables()方法递归地探索 View 树并且:

  1. 删除所有背景可绘制对象上的回调
  2. 删除每个 View 组上的子级

关于android - java.lang.OutOfMemory错误: bitmap size exceeds VM budget - Android,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29104063/

相关文章:

java - 如何使用 Android SDK 在 onCreate 语句中动态更改 Activity 的背景颜色?

c++ - STL 能否帮助解决内存碎片问题

java - C 内存泄漏与 packetsender 套接字

Android -- 为什么我的应用程序使用大约 40MB 的缓存后台进程?

c - Cygwin 中的内存泄漏检测工具

android - 使用 Android ADK 与 Arduino Mega ADK 通信时 build.xml 的问题

android - 为什么我的 Gradle APK 比 Ant 的大?

java - Sharedpreferences 在 onCreateOptionsMenu 中不起作用

javascript - 您使用什么工具和技术来修复浏览器内存泄漏?

c++ - 按地址访问结构中的元素