11

我的应用程序的主要目的是以如下方式显示图像,如图所示

在此处输入图像描述

private void setSelectedImage(int selectedImagePosition) 
{

    BitmapDrawable bd = (BitmapDrawable) drawables.get(selectedImagePosition);
    Bitmap b = Bitmap.createScaledBitmap(bd.getBitmap(), (int) (bd.getIntrinsicHeight() * 0.9), (int) (bd.getIntrinsicWidth() * 0.7), false);
    selectedImageView.setImageBitmap(b);
    selectedImageView.setScaleType(ScaleType.FIT_XY);

}

详细代码可以在这里找到

在下一行抛出异常

Bitmap b = Bitmap.createScaledBitmap(bd.getBitmap(), (int) (bd.getIntrinsicHeight() * 0.9), (int) (bd.getIntrinsicWidth() * 0.7), false);

上面的函数是从调用的onItemSelected。**该应用程序在 2.2 和 2.3 上仍然运行良好,但在 4.1 上立即抛出异常 上面的代码工作正常,但抛出以下异常。我在 2.2 和 2.3 中没有看到任何崩溃,但在 4.1 中它立即崩溃了 Jelly bean 中的内存管理有什么重大区别吗?**:

java.lang.OutOfMemoryError
AndroidRuntime(2616):   at android.graphics.Bitmap.nativeCreate(Native Method)
AndroidRuntime(2616):   at android.graphics.Bitmap.createBitmap(Bitmap.java:640)
AndroidRuntime(2616):   at android.graphics.Bitmap.createBitmap(Bitmap.java:586) 
AndroidRuntime(2616):   at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:466)
AndroidRuntime(2616):   at com.rdx.gallery.GalleryDemoActivity.setSelectedImage(GalleryDemoActivity.java:183)
4

3 回答 3

26

需要注意的是,以下代码可能会导致异常:

Bitmap bitmap = Bitmap.createScaledBitmap(oldBitmap, newWidth, newHeight, true); 
oldBitmap.recycle();

正确的是:

Bitmap bitmap = Bitmap.createScaledBitmap(oldBitmap, newWidth, newHeight, true); 
if (oldBitmap!= bitmap){
     oldBitmap.recycle();
}

因为文档说:

如果指定的宽度和高度与源 btimap 的当前宽度和高度相同,则返回源位图,现在创建新的位图。

于 2013-11-11T13:01:24.450 回答
13

http://www.youtube.com/watch?v=_CruQY55HOk。在andorid 3.0 之后,位图像素数据存储在堆上。看来您超出了堆内存大小。不要仅仅因为您的应用程序需要大堆而不使用大堆。堆的大小越大,垃圾收集就越规律。该视频对该主题有很好的解释。

不使用时也回收位图。堆上的垃圾收集是由我的标记和扫描完成的,所以当你回收位图时它会释放内存。所以你的堆大小不会增长和内存不足。

 bitmap.recycle();

http://developer.android.com/training/displaying-bitmaps/load-bitmap.html。有关有效加载位图的文档。看看在内存中加载缩小版本。

除此之外,您还可以使用 Universal Image Loader。https://github.com/nostra13/Android-Universal-Image-Loader

https://github.com/thest1/LazyList。延迟加载图像。

两者都使用缓存。

于 2013-03-21T16:02:39.370 回答
5

您正在尝试访问更多的内存。尝试使用

 BitmapFactory.Options opts=new BitmapFactory.Options();
        opts.inDither=false;                    
        opts.inSampleSize = 8;                   
        opts.inPurgeable=true;                 
        opts.inInputShareable=true;             
        opts.inTempStorage=new byte[16 * 1024]; 

Bitmap.createScaledBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.h1)
        , 65,65, true),

另请查看以下链接以增加内存

http://developer.android.com/reference/android/R.styleable.html#AndroidManifestApplication_largeHeap

检测 Android 中的应用程序堆大小

编辑 1

尝试使用 nostras 图像下载器,您可以使用它在本地存储中显示图像。它管理内存非常好......

https://github.com/nostra13/Android-Universal-Image-Loader

于 2013-03-21T15:51:02.510 回答