加载位图时出现OutOfMemoryError

时间:2014-06-23 14:52:45

标签: android image bitmap out-of-memory

我正在创建的应用程序需要从我们的服务器中提取许多图像,并显示在页面上。用户可以进入几个不同的类别,每个类别都有自己的图像。问题是在连续2-3个类别(取决于这些类别中的图像数量)之后,应用程序没有更多内存,并且无法在不崩溃的情况下显示位图。

我希望能够做的是每次用户进入新类别时清除内存,以便旧类别的图像不再存储在内存中,从而为相关类别的图像腾出空间。我不确定这是不是一个很好的方法,或者如果它是如何做到的。

如果有人有更好的解决方案,请告诉我。抛出的一个想法是一次只加载~20张图像,并等到用户在加载更多之前滚动到底部,但是由于我们的客户付费将他们的图像放在应用程序上,这将导致某些图像的流量减少,所以这不是理想的解决方案。然而,这不是不可能的。

以下是我用来加载图片的代码: 编辑:我的错误我发布了错误的代码,这是我正在使用的真实代码:

@SuppressWarnings("deprecation")
public Drawable loadImageFromWebOperations(String url, String imagePath) {
    try {
        if(Global.couponBitmaps.get(imagePath) != null){
            scaledHeight = Global.couponBitmaps.get(imagePath).getHeight();
            return new BitmapDrawable(getResources(), Global.couponBitmaps.get(imagePath));
        }
        Drawable d = null;
        File f = new File(getBaseContext().getFilesDir().getPath().toString() + "/" + imagePath + ".png");
        if (f.exists()) {
            Display display = getWindowManager().getDefaultDisplay();
            Point size = new Point();
            int scaledWidth = 0;
            try {
                display.getSize(size);
                scaledWidth = size.x;
            } catch (java.lang.NoSuchMethodError ignore) {
                scaledWidth = display.getWidth();
            }
            Bitmap bitmap = null;

            BitmapScaler scaler = new BitmapScaler(f, scaledWidth);
            bitmap = scaler.getScaled();

            scaledHeight = bitmap.getHeight();

            d = new BitmapDrawable(getResources(), bitmap);
            Global.couponBitmaps.put(imagePath, bitmap);
        } else {
            Display display = getWindowManager().getDefaultDisplay();
            Point size = new Point();
            int scaledWidth = 0;
            try {
                display.getSize(size);
                scaledWidth = size.x;
            } catch (java.lang.NoSuchMethodError ignore) {
                scaledWidth = display.getWidth();
            }
            Bitmap bitmap = BitmapFactory.decodeStream((InputStream) new URL(url).getContent());
            int height = bitmap.getHeight();
            int width = bitmap.getWidth();
            scaledHeight =  (int) (((scaledWidth * 1.0) / width) * height);
            f.getParentFile().mkdirs();
            f.createNewFile();
            OutputStream output = new FileOutputStream(f);
            bitmap.compress(Bitmap.CompressFormat.PNG, 90, output);
            output.close();
            bitmap = Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, false);
            d = new BitmapDrawable(getResources(), bitmap);
            Global.couponBitmaps.put(imagePath, bitmap);
        }
        return d;
    } catch (MalformedURLException e) {
        e.printStackTrace();
        return null;
    } catch (IOException e) {
        e.printStackTrace();
        return null;
    } catch (OutOfMemoryError e){
        e.printStackTrace();
        return null;
    }
}

如果有人知道是否有更有效的方式加载图像,或者在绘制图像之前有办法清除内存,我们将不胜感激,谢谢。

2 个答案:

答案 0 :(得分:3)

由于您从服务器加载Bitmaps,因此您应该使用图片加载库

强大的库例如:

它们允许您在您的Bitmap和加载过程中执行几乎任何的操作。也支持Chaching。

在我看来,

UniversalImageLoader功能稍强,Picasso更容易使用。

答案 1 :(得分:0)

每次创建新的Drawable和BitmapDrawable时,都会使用一个Drawable并刷新图像。