在图像的圆角处出了Memeory

时间:2017-03-25 09:44:25

标签: java android bitmap imageview out-of-memory

我有一个FrameLayout,其中有三个图像,其中第一个(左侧)和第二个(右侧)图像是从一个角落舍入的,我使用BitmapDrawable然后创建它通过这种方法舍入图像。

public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int topLeftX, int topLeftY, int topRightX, int topRightY, int bottomRightX, int bottomRightY, int bottomLeftX, int bottomLeftY) {
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        // the float array passed to this function defines the x/y values of the corners
        // it starts top-left and works clockwise
        // so top-left-x, top-left-y, top-right-x etc
        RoundRectShape rrs = new RoundRectShape(new float[]{topLeftX, topLeftY, topRightX, topRightY, bottomRightX, bottomRightY, bottomLeftX, bottomLeftY}, null, null);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setAntiAlias(true);
        paint.setColor(0xFF000000);
        rrs.resize(bitmap.getWidth(), bitmap.getHeight());
        rrs.draw(canvas, paint);
        paint.setXfermode(new PorterDuffXfermode(android.graphics.PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);
        return output;
    }

问题: 它运作良好,但我的应用程序有更多的图像,所以有时当应用程序频繁使用它的崩溃并产生此错误。

java.lang.OutOfMemoryError: Failed to allocate a 406992 byte allocation with 397304 free bytes and 387KB until OOM
                                                                              at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
                                                                              at android.graphics.Bitmap.nativeCreate(Native Method)
                                                                              at android.graphics.Bitmap.createBitmap(Bitmap.java:857)
                                                                              at android.graphics.Bitmap.createBitmap(Bitmap.java:834)
                                                                              at android.graphics.Bitmap.createBitmap(Bitmap.java:801)

我也试过使用RoundedBitmapDrawable Class,但它只适用于舍入所有角落。如果有任何其他方法或方法可以解决我的问题,请告诉我。

3 个答案:

答案 0 :(得分:0)

在AndroidManifest.xml文件中添加largeHeap,

<application
    android:largeHeap="true"
    ...
    ...
</application>

答案 1 :(得分:0)

当你的Bitmap完成它的工作,然后让它循环并且为null。

if(bitmap!=null)
{
    bitmap.recycle();
    bitmap=null;
}

答案 2 :(得分:0)

就像@Jaspreet Kaur提到的那样,你的代码没有释放旧位图的内存。但是,这可能有点复杂。假设你正在使用某个框架加载图像,所以基本上这些框架将使用Lru缓存来缓存你的图像。如果是这样的话就会出现问题:

  1. 原始图片将保留在图书馆的LruCache中,当图片被加载时会自动回收。
  2. 您的新圆角图像未存储在库的LruCache中,这意味着您需要管理自己的LruCache并稍后释放图像。
  3. 我怀疑你可以访问图书馆的LruCache。我建议尝试其他方式,例如,如果你使用Glide然后尝试实现自定义转换,因为它会为你处理内存管理。

    如果您没有使用任何库来加载图像,我相信您必须使用可随时访问的LruCache,就像@Jaspreet Kaur一样,免费或回收传入的旧位图并将新图像保存在LruCache中然后当LruCache达到内存限制时,它将负责释放图像。

    希望这会有所帮助。