java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@358df999

简介: java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@358df999

在做Android的开发的时候,在ListView 或是 GridView中需要加载大量的图片,为了避免加载过多的图片引起OutOfMemory错误,设置了一个图片缓存列表 Map> imageCache , 并对其进行维护,在图片加载到一定数量的时候,就手动回收掉之前加载图片的bitmap,此时就引起了如下错误:

Java代码  


  1. java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41de4380  
  2.    at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026)  
  3.    at android.graphics.Canvas.drawBitmap(Canvas.java:1127)  
  4.    at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)  
  5.    at android.widget.ImageView.onDraw(ImageView.java:961)  
  6.    at android.view.View.draw(View.java:13458)  
  7.    at android.view.View.draw(View.java:13342)  
  8.    at android.view.ViewGroup.drawChild(ViewGroup.java:2929)  
  9.    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)  
  10.    at android.view.View.draw(View.java:13461)  
  11.    at android.view.View.draw(View.java:13342)  

图片手动回收部分代码:

Java代码  


  1. Bitmap removeBitmap = softReference.get();  
  2. if(removeBitmap != null && !removeBitmap.isRecycled()){  
  3.    removeBitmap.recycle(); //此句造成的以上异常  
  4.    removeBitmap = null;  
  5. }  

网上有好多人说应该把recycle()去掉,个人认为去掉后会引起内存持续增长,虽然将bitmap设置为了null,但是系统并没有对其进行真正的回收,仍然占有内存,即是调用了System.gc() 强制回后以后,内存仍然没有下去,如果依靠内存达到上限时系统自己回收的话,个人觉得太晚了,已经对应用造成了影响,应用应该是比较卡了,所以还是赞同加上bitmap.recycle() ,但是又会引起 Canvas: trying to use a recycled bitmap 异常,困扰了很久,开始尝试从其它方面着手来解决这个问题,即然是异常就应该能够捕获到,但是在Adapter里的getView()方法里进行捕获的时候,时机晚了,没有捕获到。现在换到在ImageViewonDraw()里进行捕获,上面的异常能够捕获。

解决方法(继承ImageView 重写onDraw()方法,捕获异常):

在重写onDraw()方法中,其实什么都没有做,只是添加了一个异常捕获,即可捕捉到上面的错误

Java代码  


  1. import android.content.Context;  
  2. import android.graphics.Canvas;  
  3. import android.util.AttributeSet;  
  4. import android.widget.ImageView;  
  5.  
  6. /**
  7. * 重写ImageView,避免引用已回收的bitmap异常
  8. *
  9. * @author zwn
  10. *
  11. */  
  12. publicclass MyImageView extends ImageView {  
  13.  
  14.    public MyImageView (Context context, AttributeSet attrs) {  
  15.        super(context, attrs);  
  16.    }  
  17.  
  18.    @Override  
  19.    protectedvoid onDraw(Canvas canvas) {  
  20.        try {  
  21.            super.onDraw(canvas);  
  22.        } catch (Exception e) {  
  23.            System.out  
  24.                    .println("MyImageView  -> onDraw() Canvas: trying to use a recycled bitmap");  
  25.        }  
  26.    }  
  27.  
  28. }  

在做Android的开发的时候,在ListView 或是 GridView中需要加载大量的图片,为了避免加载过多的图片引起OutOfMemory错误,设置了一个图片缓存列表 Map> imageCache , 并对其进行维护,在图片加载到一定数量的时候,就手动回收掉之前加载图片的bitmap,此时就引起了如下错误:

Java代码  


  1. java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@41de4380  
  2.    at android.graphics.Canvas.throwIfRecycled(Canvas.java:1026)  
  3.    at android.graphics.Canvas.drawBitmap(Canvas.java:1127)  
  4.    at android.graphics.drawable.BitmapDrawable.draw(BitmapDrawable.java:393)  
  5.    at android.widget.ImageView.onDraw(ImageView.java:961)  
  6.    at android.view.View.draw(View.java:13458)  
  7.    at android.view.View.draw(View.java:13342)  
  8.    at android.view.ViewGroup.drawChild(ViewGroup.java:2929)  
  9.    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2799)  
  10.    at android.view.View.draw(View.java:13461)  
  11.    at android.view.View.draw(View.java:13342)  

图片手动回收部分代码:

Java代码  


  1. Bitmap removeBitmap = softReference.get();  
  2. if(removeBitmap != null && !removeBitmap.isRecycled()){  
  3.    removeBitmap.recycle(); //此句造成的以上异常  
  4.    removeBitmap = null;  
  5. }  

网上有好多人说应该把recycle()去掉,个人认为去掉后会引起内存持续增长,虽然将bitmap设置为了null,但是系统并没有对其进行真正的回收,仍然占有内存,即是调用了System.gc() 强制回后以后,内存仍然没有下去,如果依靠内存达到上限时系统自己回收的话,个人觉得太晚了,已经对应用造成了影响,应用应该是比较卡了,所以还是赞同加上bitmap.recycle() ,但是又会引起 Canvas: trying to use a recycled bitmap 异常,困扰了很久,开始尝试从其它方面着手来解决这个问题,即然是异常就应该能够捕获到,但是在Adapter里的getView()方法里进行捕获的时候,时机晚了,没有捕获到。现在换到在ImageViewonDraw()里进行捕获,上面的异常能够捕获。

解决方法(继承ImageView 重写onDraw()方法,捕获异常):

在重写onDraw()方法中,其实什么都没有做,只是添加了一个异常捕获,即可捕捉到上面的错误

Java代码  


  1. import android.content.Context;  
  2. import android.graphics.Canvas;  
  3. import android.util.AttributeSet;  
  4. import android.widget.ImageView;  
  5.  
  6. /**
  7. * 重写ImageView,避免引用已回收的bitmap异常
  8. *
  9. * @author zwn
  10. *
  11. */  
  12. publicclass MyImageView extends ImageView {  
  13.  
  14.    public MyImageView (Context context, AttributeSet attrs) {  
  15.        super(context, attrs);  
  16.    }  
  17.  
  18.    @Override  
  19.    protectedvoid onDraw(Canvas canvas) {  
  20.        try {  
  21.            super.onDraw(canvas);  
  22.        } catch (Exception e) {  
  23.            System.out  
  24.                    .println("MyImageView  -> onDraw() Canvas: trying to use a recycled bitmap");  
  25.        }  
  26.    }  
  27.  
  28. }  
目录
打赏
0
0
0
0
570
分享
相关文章
|
3月前
|
Bitmap位图(Java实现)
本文介绍了使用Java实现一个简单的Bitmap,通过自定义byte数组存储数据,提供put和exist方法分别用于插入数据和查询数据是否存在。Bitmap利用位操作高效地管理大量布尔值,适用于空间优化的场景。代码中详细解释了位图的核心原理、方法实现及边界检查。后续计划探讨位图在海量数据去重中的应用及JDK BitSet源码分析。
218 7
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
java spring 项目若依框架启动失败,启动不了服务提示端口8080占用escription: Web server failed to start. Port 8080 was already in use. Action: Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port-优雅草卓伊凡解决方案
60 7
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
在Android应用开发中,追求卓越性能是不变的主题。本文介绍如何利用Android NDK(Native Development Kit)结合Java与C++进行混合编程,提升应用性能。从环境搭建到JNI接口设计,再到实战示例,全面展示NDK的优势与应用技巧,助你打造高性能应用。通过具体案例,如计算斐波那契数列,详细讲解Java与C++的协作流程,帮助开发者掌握NDK开发精髓,实现高效计算与硬件交互。
225 1
Android经典实战之Kotlin的delay函数和Java中的Thread.sleep有什么不同?
本文介绍了 Kotlin 中的 `delay` 函数与 Java 中 `Thread.sleep` 方法的区别。两者均可暂停代码执行,但 `delay` 适用于协程,非阻塞且高效;`Thread.sleep` 则阻塞当前线程。理解这些差异有助于提高程序效率与可读性。
110 1
Cannot create android app from an archive...containing both DEX and Java-bytecode content
Cannot create android app from an archive...containing both DEX and Java-bytecode content
69 2
🚀Android NDK开发实战!Java与C++混合编程,打造极致性能体验!📊
【7月更文挑战第28天】在 Android 开发中, NDK 让 Java 与 C++ 混合编程成为可能, 从而提升应用性能。**为何选 NDK?** C++ 在执行效率与内存管理上优于 Java, 特别适合高性能需求场景。**环境搭建** 需 Android Studio 和 NDK, 工具如 CMake。**JNI** 构建 Java-C++ 交互, 通过声明 `native` 方法并在 C++ 中实现。**实战** 示例: 使用 C++ 计算斐波那契数列以提高效率。**总结** 混合编程增强性能, 但增加复杂性, 使用前需谨慎评估。
192 4
|
8月前
|
Java中使用redis的bitMap实现签到功能
这个实现示例提供了一种灵活、高效的方式,展示了如何使用Redis来解决现实中的问题。
367 2
|
8月前
|
Android经典面试题之Java中获取时间戳的方式有哪些?有什么区别?
在Java中获取时间戳有多种方式,包括`System.currentTimeMillis()`(毫秒级,适用于日志和计时)、`System.nanoTime()`(纳秒级,高精度计时)、`Instant.now().toEpochMilli()`(毫秒级,ISO-8601标准)和`Instant.now().getEpochSecond()`(秒级)。`Timestamp.valueOf(LocalDateTime.now()).getTime()`适用于数据库操作。选择方法取决于精度、用途和时间起点的需求。
100 3
Android面试题之Java 泛型和Kotlin泛型
**Java泛型是JDK5引入的特性,用于编译时类型检查和安全。泛型擦除会在运行时移除类型参数,用Object或边界类型替换。这导致几个限制:不能直接创建泛型实例,不能使用instanceof,泛型数组与协变冲突,以及在静态上下文中的限制。通配符如<?>用于增强灵活性,<? extends T>只读,<? super T>只写。面试题涉及泛型原理和擦除机制。
57 3
Android面试题之Java 泛型和Kotlin泛型
Android自定义View之Canvas一文搞定
这篇文章介绍了Android自定义View中如何使用Canvas和Paint来绘制图形。Canvas可理解为画布,用于绘制各种形状如文字、点、线、矩形、圆角矩形、圆和弧。常见API包括`drawText()`、`drawPoint()`、`drawLine()`、`drawRect()`等。文章还提到了Canvas的保存、恢复、平移和旋转方法,通过绘制钟表盘的例子展示了如何实际应用。总结关键点:Canvas与Paint结合用于图像绘制,掌握Canvas的基本绘图函数及坐标变换操作是自定义View的关键。
143 0
Android自定义View之Canvas一文搞定

热门文章

最新文章

  • 1
    android FragmentManager 删除所有Fragment 重建
    18
  • 2
    Android实战经验之Kotlin中快速实现MVI架构
    30
  • 3
    即时通讯安全篇(一):正确地理解和使用Android端加密算法
    35
  • 4
    escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
    42
  • 5
    【01】噩梦终结flutter配安卓android鸿蒙harmonyOS 以及next调试环境配鸿蒙和ios真机调试环境-flutter项目安卓环境配置-gradle-agp-ndkVersion模拟器运行真机测试环境-本地环境搭建-如何快速搭建android本地运行环境-优雅草卓伊凡-很多人在这步就被难倒了
    142
  • 6
    Cellebrite UFED 4PC 7.71 (Windows) - Android 和 iOS 移动设备取证软件
    46
  • 7
    【03】仿站技术之python技术,看完学会再也不用去购买收费工具了-修改整体页面做好安卓下载发给客户-并且开始提交网站公安备案-作为APP下载落地页文娱产品一定要备案-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    58
  • 8
    Android历史版本与APK文件结构
    159
  • 9
    【02】仿站技术之python技术,看完学会再也不用去购买收费工具了-本次找了小影-感觉页面很好看-本次是爬取vue需要用到Puppeteer库用node.js扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-优雅草卓伊凡
    48
  • 10
    【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
    41
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等