画布:尝试使用已回收的位图android

24

我一直遇到这个问题,不知道该怎么办。

我使用了 这个 库,在获得裁剪后的图像后,将其保存在静态变量中并移动到下一个活动。当我到达下一个活动时,我引用该静态变量以获取位图并尝试缩小它,但是它给我报错。

这是我所做的。

public void buttonCropClick(View view) throws IOException
{
    imageView.setDrawingCacheEnabled(true);
    imageView.buildDrawingCache(true);
    Snapshot.CroppedBitmap = imageView.getDrawingCache(true);
    imageView.setDrawingCacheEnabled(false);
    startActivity(new Intent(this,RecommendationInfo.class));
}

RecommendationInfo类中,我在下面这行代码中获取位图:Snapshot.CroppedBitmap = imageView.getDrawingCache(true); 然后我将此位图保存到静态变量中,在下一个活动中引用并传递给以下函数。

public static Bitmap scaleDown(Bitmap realImage,boolean filter) {

    float maxImageSize = HeightToSet;
    float ratio = Math.min(
            (float) maxImageSize / realImage.getWidth(),
            (float) maxImageSize / realImage.getHeight());
    int width = Math.round((float) ratio * realImage.getWidth());
    int height = Math.round((float) ratio * realImage.getHeight());

    // Error here
    Bitmap newBitmap = Bitmap.createScaledBitmap(realImage, width,height, filter);
    return newBitmap;
}

我已经尝试了调用bitmap.recycle()方法,为什么我还是遇到这个问题?我该怎么解决它?以下是我的logcat日志。

07-14 03:09:43.713: E/AndroidRuntime(19653): FATAL EXCEPTION: main
07-14 03:09:43.713: E/AndroidRuntime(19653): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@4059b8b8
07-14 03:09:43.713: E/AndroidRuntime(19653):    at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at android.graphics.Canvas.drawBitmap(Canvas.java:1012)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at android.graphics.Bitmap.createBitmap(Bitmap.java:462)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:349)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at com.example.Libraries.Snapshot.scaleDown(Snapshot.java:42)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at com.example.androidtestproject.RecommendationInfo.SetRecommendationValues(RecommendationInfo.java:195)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at com.example.androidtestproject.RecommendationInfo.access$5(RecommendationInfo.java:183)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at com.example.androidtestproject.RecommendationInfo$1.onClick(RecommendationInfo.java:154)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at android.view.View.performClick(View.java:2552)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at android.view.View$PerformClick.run(View.java:9229)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at android.os.Handler.handleCallback(Handler.java:587)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at android.os.Handler.dispatchMessage(Handler.java:92)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at android.os.Looper.loop(Looper.java:138)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at android.app.ActivityThread.main(ActivityThread.java:3701)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at java.lang.reflect.Method.invokeNative(Native Method)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at java.lang.reflect.Method.invoke(Method.java:507)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:878)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:636)
07-14 03:09:43.713: E/AndroidRuntime(19653):    at dalvik.system.NativeStart.main(Native Method)
07-14 03:09:45.515: E/TAG(20039): End of input at character 0 of 

它给你什么错误? - Alamri
我已经更新了问题,请检查。 - Mj1992
您的位图已经被释放,因此在回收后无法调用该位图。在启动其他活动之前,请检查是否正在回收位图。 - Kosh
2
createScaledImage 后添加 if (newBitmap != realImage) {realImage.recycle(); realImage = newBitmap ;} System.gc();,并且像 k0sh 提到的那样... 确保在将位图传递到下一个活动之前不要首先回收它。 - Alamri
仍然出现相同的错误。我尝试了你的代码。 - Mj1992
3个回答

43

在将位图传递给静态变量之前,请对其进行复制。

Snapshot.CroppedBitmap = imageView.getDrawingCache(true);

Snapshot.CroppedBitmap = Bitmap.createBitmap(imageView.getDrawingCache(true));

很可能当imageView不再需要时,为了良好的实践,它正在回收其绘图缓存。通过将其复制出来,您保留了对ImageView丢弃的位图的引用。只需复制一个可以自行管理的副本即可!


尝试在Android中使用回收的位图会出现错误,我的代码也出现了相同的错误,我需要改变什么? - Mahesh

3

首先需要复制原始图像:

Bitmap bitmap = webview.getDrawingCache();
if (bitmap != null) {
        Snapshot.CroppedBitmap.setImageBitmap(bitmap.copy(bitmap.getConfig(), false));
}
  • 使用createBitmap不一定会创建源位图的副本,因而可能会导致相同的错误。

java.lang.IllegalStateException: 无法复制已回收的位图。 - joecizac

0
在我的情况下,我必须将先前的位图复制到新的位图,并将其设置为可变。就这样。
Bitmap copy = previousBitmap.copy(Bitmap.Config.ARGB_8888, true);
现在我可以对位图执行新的操作。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接