Canvas: trying to use a recycled bitmap android.graphics.Bitmap in Android

旧巷老猫 提交于 2019-11-28 18:33:51

Try to add this before calling recycle() methods to make sure bitmap isn't already recycled:

if (mBitmap != null && !mBitmap.isRecycled()) {
    mBitmap.recycle();
    mBitmap = null; 
}
oli

For those that did not find a solution so far. I had the same problem. I tried to recycle a bitmap in onPause like this:

final Drawable drawable = mImageView.getDrawable();
if (drawable instanceof BitmapDrawable) {
    BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
    Bitmap bitmap = bitmapDrawable.getBitmap();
    bitmap.recycle();
}

if (preView != null && !preView.isRecycled()) {
    preView.recycle();
    preView = null;
}

After returning back i got the exception: "Canvas: trying to use a recycled bitmap"

Solution for me: I had to add the following

mImageView.setImageBitmap(null);

In my case error was caused because I changed visibility from gone to visible (or vice versa) of an element of the layout. And as consequence the space for the imageview and the bitmap created changed, so recycling caused app to crash. Avoid this and your problem will be fix.

Android doesn't allows us reuse recycled Bitmap .just comment the bitmap.recycle() to resolve this error. For more details click here

In my case, i have inflate a layout containing imageview with src image where i have faced same error. That case, problem could be resolved by adding source image programmatically like:

((ImageView)view.findViewById(R.id.imageview)).setImageBitmap(BitmapFactory.decodeResource(getContext().getResources(),
                R.drawable.testimage));

This should fix the issue in accordance to the android documentation here : https://developer.android.com/topic/performance/graphics/manage-memory#java Here's the code just incase the link doesn't work .

    private int cacheRefCount = 0;
private int displayRefCount = 0;
...
// Notify the drawable that the displayed state has changed.
// Keep a count to determine when the drawable is no longer displayed.
public void setIsDisplayed(boolean isDisplayed) {
    synchronized (this) {
        if (isDisplayed) {
            displayRefCount++;
            hasBeenDisplayed = true;
        } else {
            displayRefCount--;
        }
    }
    // Check to see if recycle() can be called.
    checkState();
}

// Notify the drawable that the cache state has changed.
// Keep a count to determine when the drawable is no longer being cached.
public void setIsCached(boolean isCached) {
    synchronized (this) {
        if (isCached) {
            cacheRefCount++;
        } else {
            cacheRefCount--;
        }
    }
    // Check to see if recycle() can be called.
    checkState();
}

private synchronized void checkState() {
    // If the drawable cache and display ref counts = 0, and this drawable
    // has been displayed, then recycle.
    if (cacheRefCount <= 0 && displayRefCount <= 0 && hasBeenDisplayed
            && hasValidBitmap()) {
        getBitmap().recycle();
    }
}

private synchronized boolean hasValidBitmap() {
    Bitmap bitmap = getBitmap();
    return bitmap != null && !bitmap.isRecycled();
}

for me the problem was i was using an arraylist to store all the bitmap values inorder to parse them into an adapter, what i was doing was that i was resizing the bitmap and then re orienting them ( the same bitmap file ) and adding them both in the arraylist

SOLUTION Created a temp instance of Bitmap and resized it and then reoriented the temp one and stored the second one in the arraylist and parsed to the adapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!