安卓关于Bitmap.isRecycled()空指针报错的解决方案

简介: 起因是我在开发功能需要使用Bitmap的方法:

前言

起因是我在开发功能需要使用Bitmap的方法:

BitmapFactory.decodeResource(my.main.getResources(),R.drawable.vector_my_need);

结果就倒大霉,运行时直接报错:

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.graphics.Bitmap.isRecycled()' on a null object reference

从日志分析,我们知道是出现了空指针,当时我先是想自己找原因,结果定位到view的源代码里,是在draw方法中,但没找到,我还没放弃,于是又定位了updateDisplayListIfDirty() 方法以及其他报错对应点,于是终于发现了是我bitmap的使用出了问题:


网络异常,图片无法展示
|


找到问题固然是好事,可是如何解决呢?这就要靠搜索了,接下来让我们看看解决方法。

正篇

正确的搜索方法

其实我在搜索上吃了许多亏,一开始在国内搜索上一直给我推C站的结果虽然有点相似但其实都相差甚远,最后我在StackOverflow上找到了答案,这也是曾经让别人困惑的一个问题:


网络异常,图片无法展示
|


可以看到有31K人浏览过此问题,所以该问题早有认可的答案:


网络异常,图片无法展示
|


意思说,我们用的vector矢量可绘制对象需要创建位图,而不是对其进行解码,且方法在下一个帖子中。

完美的解决方案

其实说到这,我已经明白,是我用SVG图资源放到安卓项目中转成Vector的xml文件,这种文件解码无法获得正确的bitmap,于是我恍然大悟的点开了下个帖子:


网络异常,图片无法展示
|


我为这个标准答案标记了中文解释,给出的是将我们的vector资源实例成Drawable对象,然后通过Bitmap的创建方法去创建成一个新的bitmap,代码如下:

Drawable d = getResources().getDrawable(R.drawable.your_drawable, your_app_theme);

这一步就是变成Drawable对象,接下来:

public static Bitmap drawableToBitmap (Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable)drawable).getBitmap();
    }
    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap); 
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);
    return bitmap;
}

这段代码是将Drawable对象转换成Bitmap封装成了工具方法,便于直接应用于主代码。

而方法内部,也分成两层:

首先第一层,我们用instanceof测试它左边的对象是否是它右边的类的实例,如果是真命题则直接返回强制转成BitmapDrawable,并直接调用它的getBitmap()方法即可。


网络异常,图片无法展示
|


而如果第一层没有成功,则由第二层处理,我们先实例化Bitmap对象,利用Bitmap的createBitmap()方法输入drawable对象的固有宽高和BItmap通道配置获取bitmap


网络异常,图片无法展示
|

网络异常,图片无法展示
|


然后调用canvas绘制bitmap,最后先用drawable的setBounds()方法为Drawable对象指定一个边界矩形,这是为了调用 draw() 方法前可以确定绘制对象将绘制的位置,接着用draw()方法完成绘制,返回最终的bitmap即完成。


网络异常,图片无法展示
|

结语

这还是我第一次这么容易就获取到了明确的正确解决方案,所以特地记录下来,当然,如果你出现了这个空指针就不需要去看英文结果了,让我们更方便的解决这个问题吧。

相关文章
|
18天前
|
安全 搜索推荐 程序员
深入探索Android系统的碎片化问题及其解决方案
在移动操作系统的世界中,Android以其开放性和灵活性赢得了广泛的市场份额。然而,这种开放性也带来了一个众所周知的问题——系统碎片化。本文旨在探讨Android系统碎片化的现状、成因以及可能的解决方案,为开发者和用户提供一种全新的视角来理解这一现象。通过分析不同版本的Android系统分布、硬件多样性以及更新机制的影响,我们提出了一系列针对性的策略,旨在减少碎片化带来的影响,提升用户体验。
|
1月前
|
开发框架 移动开发 Android开发
安卓与iOS开发中的跨平台解决方案:Flutter入门
【9月更文挑战第30天】在移动应用开发的广阔舞台上,安卓和iOS两大操作系统各自占据半壁江山。开发者们常常面临着选择:是专注于单一平台深耕细作,还是寻找一种能够横跨两大系统的开发方案?Flutter,作为一种新兴的跨平台UI工具包,正以其现代、响应式的特点赢得开发者的青睐。本文将带你一探究竟,从Flutter的基础概念到实战应用,深入浅出地介绍这一技术的魅力所在。
80 7
|
2月前
|
开发框架 前端开发 Android开发
安卓与iOS开发中的跨平台解决方案
【9月更文挑战第27天】在移动应用开发的广阔天地中,安卓和iOS两大操作系统如同双子星座般耀眼。开发者们在这两大平台上追逐着创新的梦想,却也面临着选择的难题。如何在保持高效的同时,实现跨平台的开发?本文将带你探索跨平台开发的魅力所在,揭示其背后的技术原理,并通过实际案例展示其应用场景。无论你是安卓的忠实拥趸,还是iOS的狂热粉丝,这篇文章都将为你打开一扇通往跨平台开发新世界的大门。
|
1月前
|
Android开发
Android开发显示头部Bar的需求解决方案--Android应用实战
Android开发显示头部Bar的需求解决方案--Android应用实战
21 0
|
3月前
|
网络安全 图形学 Android开发
Unity与安卓丨AS报错:SSL peer shut down incorrectly
Unity与安卓丨AS报错:SSL peer shut down incorrectly
Unity与安卓丨AS报错:SSL peer shut down incorrectly
|
3月前
|
前端开发 开发工具 Android开发
探索安卓与iOS应用开发:跨平台解决方案的崛起
【8月更文挑战第27天】在移动设备日益普及的今天,安卓和iOS系统占据了市场的主导地位。开发者们面临着一个重要问题:是选择专注于单一平台,还是寻找一种能够同时覆盖两大系统的解决方案?本文将探讨跨平台开发工具的优势,分析它们如何改变了移动应用的开发格局,并分享一些实用的开发技巧。无论你是新手还是资深开发者,这篇文章都将为你提供有价值的见解和建议。
|
3月前
|
开发工具 图形学 Android开发
Unity与安卓丨unity报错:SDK Tools version 0.0 < 26.1.1
Unity与安卓丨unity报错:SDK Tools version 0.0 < 26.1.1
|
3月前
|
API Android开发 图形学
UNITY与安卓⭐三、安卓报错答疑合集
UNITY与安卓⭐三、安卓报错答疑合集
|
3月前
|
Java Android开发
解决Android编译报错:Unable to make field private final java.lang.String java.io.File.path accessible
解决Android编译报错:Unable to make field private final java.lang.String java.io.File.path accessible
488 1
|
3月前
|
Android开发
解決Android报错:Could not initialize class org.codehaus.groovy.reflection.ReflectionCache
解決Android报错:Could not initialize class org.codehaus.groovy.reflection.ReflectionCache
108 1
下一篇
无影云桌面