碰到一个诡异的bitmap回收问题,抛出了使用了recycled的bitmap。

最终分析是Bitmap.createBitmap(Bitmap bitmap)造成的,Bitmap.createBitmap(。。。)都有此可能。

这个方法的注释如下:

Returns an immutable bitmap from subset of the source bitmap, transformed by the optional matrix. The new bitmap may be the same object as source, or a copy may have been made. It is initialized with the same density as the original bitmap. If the source bitmap is immutable and the requested subset is the same as the source bitmap itself, then the source bitmap is returned and no new bitmap is created.

所以你在使用它的时候很可能会返回给你一个你传进来的bitmap。

所以如果你按照你的设计把那个认为是临时变量的bitmap回收掉之后,殊不知不该回收的也回收了。

之前好像在哪里看到过有朋友说用Bitmap.createBitmap构造出来的bitmap回收的时候把传入的也连带回收了,并且没找到原因。当时也没在意,并且那边也没有结贴。现在想起来,估计就是这个方法造成的。

翻看Bitmap.java,找到createBitmap都是调用的这个重构方法:

public static Bitmap createBitmap(Bitmap source, int x, int y, int width, int height,

Matrix m, boolean filter) {

checkXYSign(x, y);

checkWidthHeight(width, height);

if (x + width > source.getWidth()) {

throw new IllegalArgumentException("x + width must be <= bitmap.width()");

}

if (y + height > source.getHeight()) {

throw new IllegalArgumentException("y + height must be <= bitmap.height()");

}

// check if we can just return our argument unchanged

if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&

height == source.getHeight() && (m == null || m.isIdentity())) {

return source;

}

int neww = width;

int newh = height;

Canvas canvas = new Canvas();

Bitmap bitmap;

Paint paint;

Rect srcR = new Rect(x, y, x + width, y + height);

RectF dstR = new RectF(0, 0, width, height);

Config newConfig = Config.ARGB_8888;

final Config config = source.getConfig();

// GIF files generate null configs, assume ARGB_8888

if (config != null) {

switch (config) {

case RGB_565:

newConfig = Config.RGB_565;

break;

case ALPHA_8:

newConfig = Config.ALPHA_8;

break;

//noinspection deprecation

case ARGB_4444:

case ARGB_8888:

default:

newConfig = Config.ARGB_8888;

break;

}

}

if (m == null || m.isIdentity()) {

bitmap = createBitmap(neww, newh, newConfig, source.hasAlpha());

paint = null;   // not needed

} else {

final boolean transformed = !m.rectStaysRect();

RectF deviceR = new RectF();

m.mapRect(deviceR, dstR);

neww = Math.round(deviceR.width());

newh = Math.round(deviceR.height());

bitmap = createBitmap(neww, newh, transformed ? Config.ARGB_8888 : newConfig,

transformed || source.hasAlpha());

canvas.translate(-deviceR.left, -deviceR.top);

canvas.concat(m);

paint = new Paint();

paint.setFilterBitmap(filter);

if (transformed) {

paint.setAntiAlias(true);

}

}

// The new bitmap was created from a known bitmap source so assume that

// they use the same density

bitmap.mDensity = source.mDensity;

canvas.setBitmap(bitmap);

canvas.drawBitmap(source, srcR, dstR, paint);

canvas.setBitmap(null);

return bitmap;

}

在这个方法里有如下逻辑:

// check if we can just return our argument unchanged

if (!source.isMutable() && x == 0 && y == 0 && width == source.getWidth() &&

height == source.getHeight() && (m == null || m.isIdentity())) {

return source;

}

因此,在满足这个逻辑的情况下,createBitmap把传进来的source直接返回了。

所以对这个方法慎用吧,需要保证创建一个拷贝的可以尝试使用Bitmap.copy(Config config, boolean isMutable)来完成设计上的需要。

android createbitmap,慎用Bitmap.createBitmap相关推荐

  1. android bitmap.createbitmap内存溢出,android bitmap oom 优化

    android使用位图显示图片,也就是像素点,jpg之类的压缩格式在android都会转成bitmap. 现在手机的分辨率也越来越高,480*800 大小的图片使用的内存大小: 480*800*32/ ...

  2. Android view转bitmap,byte[]转Bitmap

    1.自定义marker布局文件即自定义view文件 <?xml version="1.0" encoding="utf-8"?> <Linea ...

  3. Android下利用Bitmap切割图片

    在自己自定义的一个组件中由于需要用图片显示数字编号,而当前图片就只有一张,上面有0-9是个数字,于是不得不考虑将其中一个个的数字切割下来,需要显示什么数字,只需要组合一下就好了. 下面是程序的关键代码 ...

  4. android bitmap 替换指定颜色,Android 实现把bitmap图片的某一部分的颜色改成其他颜色...

    把bitmap图片的某一部分的颜色改成其他颜色 private Bitmap ChangeBitmap(Bitmap bitmap){ int bitmap_h; int bitmap_w; int ...

  5. Android pdf转换bitmap保存到本地

    Android pdf转换bitmap保存到本地 PDF转换成图片保存到本地 Android有自带的API提供 首先要把PDF文件下载到本地,下载成功使用 下载就最简单的IO下载都行 例如: try ...

  6. android bitmap设置透明度,Android 设置图片 Bitmap任意透明度

    两种思路,第一种思路是通过对Bitmap进行操作,将Bitmap的像素值get到一个int[]数组里,因为在android里Bitmap通常是ARGB8888格式,所以最高位就是A通道的值,对齐进行改 ...

  7. Android 设置图片 Bitmap任意透明度

    两种思路,第一种思路是通过对Bitmap进行操作,将Bitmap的像素值get到一个int[]数组里,因为在android里Bitmap通常是ARGB8888格式,所以最高位就是A通道的值,对齐进行改 ...

  8. Android JNI操作Bitmap实现黑白图片

    最近想练习一下NDK,基于我接下来的目标是多媒体,多以想多点学习一下关于滤镜的知识,黑白滤镜是最简单的了. 这里实现的是将一张彩色图片转成黑白图片,是黑白滤镜的基础! 直接上码: // java 代码 ...

  9. android bitmap 替换指定颜色,Android实现把bitmap图片的某一部分的颜色改成其他颜色的方法...

    Android实现把bitmap图片的某一部分的颜色改成其他颜色的方法 发布时间:2020-07-29 14:11:15 来源:亿速云 阅读:107 作者:小猪 这篇文章主要讲解了Android实现把 ...

最新文章

  1. zabbix安装报错
  2. Python基础教程(五):数字、字符串
  3. 自嘲尾款人、丁工人?今年双十一就没想让你做人
  4. linux清理备份日志,服务器日志清理备份
  5. php按城市显示搜索结果,搜索结果页(通过数据库搜索)
  6. 注意了,这些数值计算的坑千万别踩!
  7. Java项目中读取properties文件
  8. Vue插槽(solt)简单案例
  9. 原始套接字与抓包过滤规则setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, ...)
  10. linux:记录一次 处理tomcat启动卡死无报错现象的曲折过程
  11. 【个人笔记】OpenCV4 C++ 图像处理与视频分析 04课
  12. # 【CrackMe】0-爆破之Acid burn
  13. 曲线运动与万有引力公式_高中物理公式大全!
  14. wine linux 目录,linux中wine的安装及使用
  15. 码农十分钟的音律概述 纯律 五度相生律 十二平均律
  16. 御坂坂的C++学习之路(7)
  17. statsby: 不用循环语句的循环
  18. 正大国际:做外盘期货主帐户有什么风险?
  19. 谷歌浏览器记住密码功能 input框黄色背景
  20. moment时间操作

热门文章

  1. 关于win10兼容ie7/8
  2. c语言.jpg图片转成数组_PDF怎么快速转换成JPG图片呢?这几款工具超实用
  3. 硬件不足?场景复杂?lumion渲染慢怎么办?
  4. 让我们看看如何搭配浅玫红风衣
  5. 斯坦福大学自然语言处理研究的《信息检索》课程
  6. 当小明来到上海,会发生什么呢?
  7. Inconsistent namespace mapping properties. Cannot initiate connection as SYSTEM:CATALOG is found but
  8. jupiter 85 2.0
  9. 618游戏蓝牙耳机推荐,最值得入手的低延迟游戏蓝牙耳机
  10. FCM模糊C均值聚类分析(Fuzzy C-means)公式推导与MATLAB程序