Java 图像圆角时内存不足

Java 图像圆角时内存不足,java,android,bitmap,imageview,out-of-memory,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 bottomLeft

我有一个
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类,但它只适用于四舍五入。如果有任何其他方法或方法可以解决我的问题,请告诉我。

在AndroidManifest.xml文件中添加largeHeap

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

当位图完成其工作时,将其循环并为空

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

就像@Jaspreet Kaur提到的,您的代码并没有释放旧位图的内存。然而,这可能有点复杂。假设您正在使用某个框架加载图像,那么这些框架基本上将使用Lru缓存来缓存您的图像。如果是这样,则存在一个问题:

  • 您的原始图像将保留在库的LruCache中,当加载更多图像时,该库将自动回收
  • 您的新圆形图像未存储在库的LruCache中,这意味着您需要管理自己的LruCache并在以后释放图像
  • 我怀疑你能进入图书馆的鲁卡什。我建议您尝试其他方法,例如,如果您正在使用Glide,那么请尝试实现自定义转换,因为它将为您提供内存管理

    如果你没有使用任何库来加载图像,我相信你必须使用LruCache,它可以访问,就像@Jaspreet Kaur提到的,释放或回收传入的旧位图,并将新图像保留在LruCache中,然后LruCache将在图像达到内存限制时释放图像


    希望这会有所帮助。

    缩小大小
    新建Rect(0,0,bitmap.getWidth(),bitmap.getHeight())
    我已经在方法中使用了这一行