我们平时设置图片的时候,几乎都忘记回收老的(背景)图片,比如:

  • TextView.setBackgroundDrawable()
  • TextView.setBackgroundResource()
  • ImageView.setImageDrawable()
  • ImageView.setImageResource()
  • ImageView.setImageBitmap()

这样造成内存浪费,积少成多,整个软件可能浪费不少内存。

如果记得优化,整个软件的内存占用会有10%~20%的下降。

// 获得ImageView当前显示的图片
Bitmap bitmap1 = ((BitmapDrawable) imageView.getBackground()).getBitmap();
Bitmap bitmap2 = Bitmap.createBitmap(bitmap1, 0, 0, bitmap1.getWidth(),bitmap1.getHeight(), matrix, true);
// 设置新的背景图片
imageView.setBackgroundDrawable(new BitmapDrawable(bitmap2));
// bitmap1确认即将不再使用,强制回收,这也是我们经常忽略的地方
if (!bitmap1.isRecycled()) {
bitmap1.recycle();
}

看上面的代码,设置新的背景之后,老的背景确定不再使用,则应该回收。

封装如下(仅针对setBackgroundXXX做了封装,其他的原理类同):

/**
* 给view设置新背景,并回收旧的背景图片<br>
* <font color=red>注意:需要确定以前的背景不被使用</font>
*
* @param v
*/
@SuppressWarnings("deprecation")
public static void setAndRecycleBackground(View v, int resID) {
// 获得ImageView当前显示的图片
Bitmap bitmap1 = null;
if (v.getBackground() != null) {
try {
//若是可转成bitmap的背景,手动回收
bitmap1 = ((BitmapDrawable) v.getBackground()).getBitmap();
} catch (ClassCastException e) {
//若无法转成bitmap,则解除引用,确保能被系统GC回收
v.getBackground().setCallback(null);
}
}
// 根据原始位图和Matrix创建新的图片
v.setBackgroundResource(resID);
// bitmap1确认即将不再使用,强制回收,这也是我们经常忽略的地方
if (bitmap1 != null && !bitmap1.isRecycled()) {
bitmap1.recycle();
}
} /**
* 给view设置新背景,并回收旧的背景图片<br>
* <font color=red>注意:需要确定以前的背景不被使用</font>
*
* @param v
*/
@SuppressWarnings("deprecation")
public static void setAndRecycleBackground(View v, BitmapDrawable imageDrawable) {
// 获得ImageView当前显示的图片
Bitmap bitmap1 = null;
if (v.getBackground() != null) {
try {
//若是可转成bitmap的背景,手动回收
bitmap1 = ((BitmapDrawable) v.getBackground()).getBitmap();
} catch (ClassCastException e) {
//若无法转成bitmap,则解除引用,确保能被系统GC回收
v.getBackground().setCallback(null);
}
}
// 根据原始位图和Matrix创建新的图片
v.setBackgroundDrawable(imageDrawable);
// bitmap1确认即将不再使用,强制回收,这也是我们经常忽略的地方
if (bitmap1 != null && !bitmap1.isRecycled()) {
bitmap1.recycle();
}
}

【Android开发坑系列】之经常被忽略的背景图片内存泄露的更多相关文章

  1. 【Android开发坑系列】之事件分发机制

    总结一下: 事件序列的定义:从手触摸屏幕(含)到离开屏幕(含)期间所发生的一系列交互事件.主要由ACTION_DOWN.ACTION_MOVE.ACTOIN_UP.ACTION_CANCEL等组成,其 ...

  2. 【Android开发坑系列】之PopupWindow

    PopupWindow在4.0之前的版本有个系统级别的BUG,必须借助一段自定义的fix代码来修复.其中mPopPm就是PopupWindow实例.java.lang.NullPointerExcep ...

  3. 【Android开发坑系列】如何让Service尽可能存活

    流行的思路如下[2015-11-20更新]: 1.让Service杀不死.Service的onStartCommand返回START_STICKY,同时onDestroy里面调用startServic ...

  4. 【Android开发坑系列】之try-catch

    try { mViewPager.postDelayed(new Runnable() { @Override public void run() { getCurrentPage().render( ...

  5. 【Android开发坑系列】之Fragment

    这个东西有顾名思义是碎片,和之前的Activity对应. 坑1:一般情况都会想当然的以为进程被杀掉之后,Fragment也会被回收 其实,Fragment有自己的生命周期,有自己的管理器(Fragme ...

  6. 【Android开发坑系列】之事件

    总结一下: 1.Touch事件分发中只有两个主角:ViewGroup和View.ViewGroup包含onInterceptTouchEvent.dispatchTouchEvent.onTouchE ...

  7. 【Android开发坑系列】之窗口管理

    关键知识要点如下(持续更新): WindowManagerService只负责管理Window,不负责图像的绘制: SurfaceFlinger负责图像的合成:

  8. Android 开发 框架系列 OkHttp拦截器

    前言 此篇博客只讲解okhttp的拦截器功能的详细使用,如果你还不太了解okhttp可以参考我另外一篇博客 Android 开发 框架系列 OkHttp使用详解 添加Interceptor的简单例子 ...

  9. Android根据Button状态(normal,focused,pressed)显示不同背景图片

    Android根据Button状态(normal,focused,pressed)显示不同背景图片 Android中Button 有focused, selected, pressed 等不同状态,通 ...

随机推荐

  1. Contacts群组添加成员,多选列表过滤已添加数据

    Group添加联系人时,Contacts默认设计不会过滤已分组的联系人.之前看到小米,oppo都做过过滤,一直懒得改. 最近客户要求group添加成员时,不显示已分组的联系人,故记录一下实现过程. p ...

  2. 5、清理mac缓存和关闭后台运行程序

    一.清理mac 缓存  1.用鼠标点击桌面,然后按快捷键Command+Shift+G前往文件夹 2.输入路径:~/Library/Caches/ 3.清除所有的数据,把所有的Caches文件夹得都行 ...

  3. 【洛谷P1080】国王游戏

    我们按照左右手数的乘积升序排序,就能使最多金币数最小了 为什么呢? 我们知道: 1)如果相邻的两个人交换位置,只会影响到这两个人的值,不会影响他人 2)假设相邻的两个人i, i + 1.设A[i] B ...

  4. java 类的关系

    在面向对象中,类与类之间的关系有泛化,依赖,关联,聚合,组合几种.其中,聚合和组合都属于关联.在具体编程中: 依赖表现为如果A类依赖于B,则B体现为A的局部变量,方法参数或静态方法的调用.eg:cla ...

  5. Source Depot 使用总结

    MS使用的Source Depot方案,主要是控制软件版本,类似的软件有SVN等,Source Depot一般使用起来也比较方便,可以灵活的配置,只要有访问权限,就可以下到对应的源代码文件. SD使用 ...

  6. Rhythmbox中文乱码

    今天在网络上找到了一个比较好的解决Rhythmbox中文乱码的问题的方法 进入你的音乐文件夹执行如下代码: mid3iconv -e GBK *.mp3 如果没有提示多试几次, 有可能系统会提示: p ...

  7. Keil的标题“礦ision3" 的改变(转)

    MDK 的标题显示成 “礦ision3",前面的这个不是u而是一个希腊字母“缪”,在中文显示中出现问题,半个汉字. 可以使用如下方法取消. 一: 光标问题 Keil uv3 中会出现光标定位 ...

  8. js promise 风格编程

    使用q 这种方式,极大的避免了回调地狱的情况产生,以后打算长久用这种方式. 再写Nodejs,再也不担心这个问题了. 以下实例,作为连接数据库的公共方法. /** * Created by Think ...

  9. SRS文档 王倩倩 201303014004

    设计阶段 Spec 图书管理系统functional spec:软件功能说明书, 主要用来说明软件的外部功能, 和用户的交互情况 (把软件当作一个黑盒子).从用户的角度描述软件产品的功能, 输入,输出 ...

  10. (译)开发优秀的虚拟现实体验:从开发I Expect You to Die中总结的六个要点

    这篇文章是我从网上找来的,我觉得他非常详细的解释了VR发展的需求和必要.我认为通过这篇文章可以让大家了解VR. 译者写在最前: 来到追光动画有好几个月了,抱歉这段时间也没有什么文章与大家分享,我现在在 ...