【问题标题】:Can't compress a recycled bitmap无法压缩回收的位图
【发布时间】:2026-01-15 02:50:01
【问题描述】:

我正在尝试将布局保存到 SDCard 中的图像中,但出现此错误。我尝试了在这个论坛中找到的几个代码,但它们都有相同的压缩调用,导致错误。

这是我用来保存图像的代码:

private Bitmap TakeImage(View v) {
        Bitmap screen = null;
        try {
            v.setDrawingCacheEnabled(true);

            v.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
                    MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
            v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());

            v.buildDrawingCache(true);
            screen = v.getDrawingCache();
            v.setDrawingCacheEnabled(false); // clear drawing cache
        } catch (Exception e) {
            e.printStackTrace();
        }
        return screen;
    }

这是将其保存在 SDCard 中的代码:

private void saveGraph(Bitmap graph, Context context) throws IOException {
        OutputStream fOut = null;
        File file = new File(Environment.getExternalStorageDirectory()
                + File.separator + "test.jpg");
        fOut = new FileOutputStream(file);

        graph.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
        fOut.flush();
        fOut.close();

        MediaStore.Images.Media.insertImage(getContentResolver(),
                file.getAbsolutePath(), file.getName(), file.getName());
}

我收到了错误:

无法在 compress 调用中压缩回收的位图!

【问题讨论】:

    标签: android android-layout


    【解决方案1】:

    这可能是导致位图被回收:

    v.setDrawingCacheEnabled(false); // clear drawing cache
    

    如果您希望位图停留更长时间,那么您应该复制它。

    【讨论】:

    • 你不应该把线拿出来;从缓存中提供的位图可以随时被拥有它的视图回收。您确实需要使用 Bitmap.copy() 来获取您自己的位图副本。
    • 你能解释一下如何复制吗?
    • 如我所说,请致电Bitmap.copy()。这是文档:developer.android.com/reference/android/graphics/…, boolean)
    • 对我有用,而且我只需要稍后将代码移到我的方法中。我在 Xamarin.Android 中检查了我的代码,并且过早将其设置回 false。
    【解决方案2】:

    这解决了我的问题。

    View drawingView = get_your_view_for_render;
    drawingView.buildDrawingCache(true);
    Bitmap bitmap = drawingView.getDrawingCache(true).copy(Config.RGB_565, false);
    drawingView.destroyDrawingCache();
    // bitmap is now OK for you to use without recycling errors.
    

    【讨论】:

      【解决方案3】:

      解决办法是: 你只需要复制位图。

      imageneViewer.setImageBitmap(lienzo.getDrawingCache().copy(Bitmap.Config.RGB_565, false));
      

      【讨论】: