在ImageView中使用Bitmap时出现OutOfMemory问题

时间:2014-01-10 05:56:01

标签: android bitmap imageview out-of-memory

我在Android应用程序中有超过8个活动所有屏幕都有很多imageView,它将使用位图图像进行渲染

当我们打开所有屏幕(活动)时,它会正常工作几次然后它将通过内存不足错误并且应用程序崩溃

这是我的代码如何显示图片,请建议如何避免这种情况/管理此内存不足问题

XML:

<?xml version="1.0" encoding="utf-8"?>    
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    
    android:layout_width="match_parent"    
    android:layout_height="match_parent"    
    android:orientation="vertical"    
    android:background="@drawable/img_background">    

   <ImageView    
        android:layout_width="match_parent"   
        android:layout_height="match_parent"    
        android:scaleType="fitCenter"    
        android:adjustViewBounds="true"       
        android:id="@+id/artifactImage"      
        android:onClick="displayFullScreenImage"/>      

</LinearLayout>    

活动:

ImageView artifact_Image = (ImageView) gridView.findViewById(R.id.artifactImage);     
artifact_Image.setImageBitmap(artifactImages[position]);       
artifact_Image.setDrawingCacheEnabled(false);

2 个答案:

答案 0 :(得分:1)

您显示的图像可能占用整个存储空间,这就是您收到此错误的原因。您可能需要查看有关如何显示位图的文档:

http://developer.android.com/training/displaying-bitmaps/index.html

在您的情况下,您应该加载图像的缩小版本。查看此链接以获取示例代码:

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html

为方便起见,我也在这里复制示例代码。

计算样本量:

public static int calculateInSampleSize(
            BitmapFactory.Options options, int reqWidth, int reqHeight) {
    // Raw height and width of image
    final int height = options.outHeight;
    final int width = options.outWidth;
    int inSampleSize = 1;

    if (height > reqHeight || width > reqWidth) {

        final int halfHeight = height / 2;
        final int halfWidth = width / 2;

        // Calculate the largest inSampleSize value that is a power of 2 and keeps both
        // height and width larger than the requested height and width.
        while ((halfHeight / inSampleSize) > reqHeight
                && (halfWidth / inSampleSize) > reqWidth) {
            inSampleSize *= 2;
        }
    }

    return inSampleSize;
}

解码位图:

public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId,
        int reqWidth, int reqHeight) {

    // First decode with inJustDecodeBounds=true to check dimensions
    final BitmapFactory.Options options = new BitmapFactory.Options();
    options.inJustDecodeBounds = true;
    BitmapFactory.decodeResource(res, resId, options);

    // Calculate inSampleSize
    options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);

    // Decode bitmap with inSampleSize set
    options.inJustDecodeBounds = false;
    return BitmapFactory.decodeResource(res, resId, options);
}

最后设置缩放位图

mImageView.setImageBitmap(
    decodeSampledBitmapFromResource(getResources(), R.id.myimage, 100, 100));

答案 1 :(得分:0)

请参阅此处有很多原因可以解释为什么在Android应用中加载位图很棘手:

  1. 移动设备通常具有受限制的系统资源。 Android设备可以为单个应用程序提供少至16MB的内存。 Android兼容性定义文档(CDD),第3.7节。虚拟机兼容性为各种屏幕尺寸和密度提供所需的最小应用程序内存。应优化应用程序以在此最小内存限制下执行。但是,请记住,许多设备配置了更高的限制。

  2. 位图会占用大量内存,尤其是对于像照片这样的丰富图像。例如,Galaxy Nexus上的相机拍摄的照片最高可达2592x1936像素(5百万像素)。如果使用的位图配置是ARGB_8888(默认情况下从Android 2.3开始),那么将此图像加载到内存中需要大约19MB的内存(2592 * 1936 * 4字节),立即耗尽某些设备上的每个应用程序限制。

  3. Android应用UI经常需要一次加载几个位图。 ListView,GridView和ViewPager等组件通常会同时在屏幕上显示多个位图,并且可以在屏幕上显示更多可能的屏幕外显示。

  4. here也是一个很好的博客,以避免内存泄漏。

    如果要加载多个没有内存错误的位图,则应使用image Loader library