Canvas:尝试在 Android 2.3 上使用回收的位图 RuntimeException

     2023-04-12     162

关键词:

【中文标题】Canvas:尝试在 Android 2.3 上使用回收的位图 RuntimeException【英文标题】:Canvas: trying to use a recycled bitmap RuntimeException on Android 2.3 【发布时间】:2013-06-25 11:13:48 【问题描述】:

我构建了一个自定义视图(类似于网格视图),它显示了许多许多图像,因此回收位图是此应用程序的必要条件。我正在使用 Lru 缓存(在下面实现)来处理位图回收。当我在 Android 2.3 设备上测试这个(并快速滚动)时,我收到以下错误消息并且应用程序崩溃了。在弄清楚如何复制该错误后,我在 Android 4.0 上对其进行了测试,它运行良好。

06-27 10:57:48.420: E/AndroidRuntime(14255): FATAL EXCEPTION: main
06-27 10:57:48.420: E/AndroidRuntime(14255): java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@407fc6b8
06-27 10:57:48.420: E/AndroidRuntime(14255):    at android.graphics.Canvas.throwIfRecycled(Canvas.java:955)
06-27 10:57:48.420: E/AndroidRuntime(14255):    at android.graphics.Canvas.drawBitmap(Canvas.java:1044)
06-27 10:57:48.420: E/AndroidRuntime(14255):    at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:325)
06-27 10:57:48.420: E/AndroidRuntime(14255):    at android.widget.ImageView.onDraw(ImageView.java:872)
etc etc

我跟踪了这​​个错误,结果发现我在将位图设置为 ImageView 之前检查了位图是否被回收。但是,位图在该步骤和 draw() 步骤之间被回收,从而导致错误。

这是我的缓存:

 sLruCache = new LinkedHashMap(容量 / 2, 0.75f, true) 
      私有静态最终长序列版本UID = -7282875042976381535L;

      @覆盖
      protected boolean removeEldestEntry(LinkedHashMap.Entry eldest) 
        如果(大小()> mCapacity)
          返回真;
         别的
          返回假;
      

      公共位图删除(对象键)
        位图 bitmap = super.remove(key);
        如果(位图!= NULL_BITMAP)
          bitmap.recycle();
        
        返回位图;
      ;

      @覆盖
      公共无效清除()
        设置键 = new HashSet(keySet());
        对于(字符串键:键)
          位图映射 = get(key);
          如果(地图!= NULL_BITMAP)
            map.recycle();
          
        
        超级清除();
      
    ;

关于为什么这会在 Android 2.3 而不是 4.0 上失败的任何想法?

【问题讨论】:

bitmap.recycle() 您正在使用回收的位图。 只有当它被从缓存中删除时。我相信 bitmap.recycle() 应该在 remove 方法中使用。另外,为什么这会在 Android 4.0 上运行? developer.android.com/training/displaying-bitmaps/…。它将在 4.0 上运行,因为在 android 3.0 及更高版本中为位图分配内存的方式发生了变化 如果不在 remove 方法中,我应该什么时候回收它们?否则我会用完内存 当不再需要位图并且不能使用回收的位图时,您应该回收它。 【参考方案1】:

我也有同样的问题。

我不得不删除所有 Bitmap.recycle() 调用。有时会导致 OutOfMemoryException。

因此,我做了一个这样的 hack:

// when I need to remove bitmap from cache
if (Build.VERSION.SDK_INT < 9 || Build.VERSION.SDK_INT > 10) 
    bmp.recycle();
   

这不是一个好的解决方案,但它可能会有所帮助。

【讨论】:

如何在 Android 上使图像透明?

】如何在Android上使图像透明?【英文标题】:HowcanImakeanimagetransparentonAndroid?【发布时间】:2011-07-0123:20:17【问题描述】:我使用的是线性布局和框架布局。在线性布局中,我保留一个图像作为背景,在框架布局中,我保留一个im... 查看详情

如何在 Android 上使背景透明 20%

】如何在Android上使背景透明20%【英文标题】:Howtomakeabackground20%transparentonAndroid【发布时间】:2012-07-0209:53:29【问题描述】:如何使Textview的背景大约透明20%(不是完全透明),而背景中有颜色(即白色)?【问题讨论】:必看**... 查看详情

如何在 Blazorise 上使验证日期不为空

...使用Blazorise模态组件开发blazor,但我无法验证DateEdit,我尝试使用@ValidationRule.IsNotEmpty,但它不起作用<ValidationValidator="@ValidationR 查看详情

RemoteServiceException 在 MIUI 11 上使我的应用程序崩溃

...间】:2021-04-1510:54:34【问题描述】:我开始收到来自运行Android11的MIUI11设备的奇怪崩溃(目前只有Mi10和Mi10lite5G)。我认为这是一个平台问题,在我的应用中没有任何内容,因为它是针对小米Android11的。 查看详情

async Task.Run lambda 表达式在 Android 上使 Unity AR 应用程序崩溃,但在 iOS 上运行良好

】asyncTask.Runlambda表达式在Android上使UnityAR应用程序崩溃,但在iOS上运行良好【英文标题】:asyncTask.RunlambdaexpressioncrashesUnityARapponandroidbutworksfineoniOS【发布时间】:2021-09-2323:34:16【问题描述】:我正在使用Unity2020.3.4和ARCore4.0.12以... 查看详情

android 2.3 上的推送通知崩溃。

】android2.3上的推送通知崩溃。【英文标题】:Pushnotificationsonandroid2.3crashed.【发布时间】:2013-03-1309:52:41【问题描述】:我正在尝试将推送通知发送到带有GCM的手机,它在带有android4的设备上运行良好,但是当我尝试在android2.3上... 查看详情

如何在Android中调用CustomView的onDraw(Canvas canvas)函数?

】如何在Android中调用CustomView的onDraw(Canvascanvas)函数?【英文标题】:HowtocallonDraw(Canvascanvas)functionofCustomViewinAndroid?【发布时间】:2020-03-0705:07:22【问题描述】:我生成一个椭圆,并尝试根据您可以在下面看到的sweepAngle_speed重塑... 查看详情

如何使用自动布局在情节提要上使网格并排 uiview 响应

...。我需要7个并排的方格,我想让它们反应灵敏。我已经尝试根据预览和下一个正方形设置每个正方形的尾随和前导,但是如果不设置宽度(什么会使其 查看详情

Android 版本 > 2.3 上的 FileNotFoundException

】Android版本>2.3上的FileNotFoundException【英文标题】:FileNotFoundExceptiononAndroidversion>2.3【发布时间】:2012-03-1708:42:55【问题描述】:我尝试将文件下载到手机上的sdcard。在Android2.1、2.2和2.3上,一切都按预期工作,但在Android4.0(... 查看详情

我可以在 Android Canvas 的范围之外绘制吗

】我可以在AndroidCanvas的范围之外绘制吗【英文标题】:CanIdrawoutsidetheboundsofanAndroidCanvas【发布时间】:2011-05-0100:09:45【问题描述】:我正在移植一个在图形环境中编写的应用程序,该应用程序允许在剪切矩形的边界之外进行绘图... 查看详情

Canvas 停止识别痕迹 Android

】Canvas停止识别痕迹Android【英文标题】:CanvasstoprecognizingtraceAndroid【发布时间】:2011-08-0416:48:34【问题描述】:尝试制作一个使用MotionEvent.ACTION_MOVE工作的画布。然而,在线程启动后,水平线绘制正确,但其他线均无效或零星。... 查看详情

如何在 Android 2.3 (Gingerbread) 上增加堆大小?

】如何在Android2.3(Gingerbread)上增加堆大小?【英文标题】:HowtoincreaseheapsizeonAndroid2.3(Gingerbread)?【发布时间】:2015-01-0407:41:56【问题描述】:当我尝试使用StringBuilder.append()创建大于4MB的String时,我收到了OutOfMemoryError。据我所知,... 查看详情

Android 2.2 和 2.3 中的 MediaMetadataRetriever

】Android2.2和2.3中的MediaMetadataRetriever【英文标题】:MediaMetadataRetrieverinAndroid2.2and2.3【发布时间】:2012-03-3114:27:13【问题描述】:我想使用MediaMetadataRetriever来显示URL音乐的封面。在Android2.2中,我尝试下面的代码,它可以工作,但... 查看详情

Android 2.2 和 2.3 中的 MediaMetadataRetriever

】Android2.2和2.3中的MediaMetadataRetriever【英文标题】:MediaMetadataRetrieverinAndroid2.2and2.3【发布时间】:2012-03-3114:27:13【问题描述】:我想使用MediaMetadataRetriever来显示URL音乐的封面。在Android2.2中,我尝试下面的代码,它可以工作,但... 查看详情

如何在 Android Canvas 中绘制带有文本的矩形按钮?

】如何在AndroidCanvas中绘制带有文本的矩形按钮?【英文标题】:HowtodrawaButtonlikerectanglewithtextinAndroidCanvas?【发布时间】:2021-06-3000:43:03【问题描述】:在Android应用程序中,我想在画布中绘制一个按钮,就像下面的图像一样我尝... 查看详情

如何在 os x 上使 Boost dylibs 通用(i386 和 x86_64)?

...onosx?【发布时间】:2013-11-2217:56:29【问题描述】:我正在尝试将Boost库编译为通用二进制文件(即包含i386和x86_64架构的构建的“胖”文件)。上网和SO我组装了以下说明。下载提升(例如来自http://www.boost.org 查看详情

Android - 如何使用 Canvas 在 OnDraw() 中设置自定义视图的宽度和高度?

】Android-如何使用Canvas在OnDraw()中设置自定义视图的宽度和高度?【英文标题】:Android-HowtosetwidthandheightforcustomviewinOnDraw()withCanvas?【发布时间】:2021-01-2810:48:41【问题描述】:我正在尝试为我使用Canvas绘制的自定义视图设置宽度... 查看详情

为啥 jquery.animate 在 textarea 上使闪烁的光标消失?

】为啥jquery.animate在textarea上使闪烁的光标消失?【英文标题】:Whyjquery.animateonatextareamaketheblinkingcursordisapears?为什么jquery.animate在textarea上使闪烁的光标消失?【发布时间】:2011-02-0811:03:42【问题描述】:我有以下代码$(document).re... 查看详情