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

  • 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. 你知不知道 Cookie正在泄露你的隐私!

    关于电脑上的Cookie,我想很多朋友都还是有所了解的,遇到诸如论坛帐号无法登录此类问题的时候,大家都知道先清除一下IE的Cookie,然后再重新登录就很有可能可以解决问题.然而,即使是最熟悉的东西也 ...

  2. Collections类常用方法总结

    1. sort 对集合进行排序 public static <T extends Comparable<? super T>> void sort(List<T> ...

  3. 【模板】【转载】区间dp

    区间动态规划问题一般都是考虑,对于每段区间,他们的最优值都是由几段更小区间的最优值得到,是分治思想的一种应用,将一个区间问题不断划分为更小的区间直至一个元素组成的区间,枚举他们的组合 ,求合并后的最优 ...

  4. bcb安装控件方法汇总

    1.BCB 菜单: Project->Options->Packages->Add[喝小酒的网摘]http://blog.const.net.cn/a/8496.htm如果是BCB6 ...

  5. Log4net日志GUI配置工具

    关于log4net的配置文章在园子里真的很多,但是有关GUI界面配置的文章确定太少,改写了一个以前很早的工具 以前的那个有很多的问题,这个基本的大的问题没有,可能一个小问题还是需要修改下,基本功能肯定 ...

  6. [SmartFoxServer概述]SFS2X特点

    SFS2X 特点概述 SFS2X采用SFS核心原理并在新的方向进行扩展,介绍了许多改善方案,同时专注于几个方面:使用简单化,通用化和性能化. *使用简单化:清除了SFS之前版本中所有不必要的复杂方法, ...

  7. dom4j 学习总结

    Dom4j is an easy to use, open source library for working with XML, XPath and XSLT on the Java platfo ...

  8. Log4j 配置数据库连接池(将日志信息保存到数据库)

    org.apache.log4j.jdbc.JDBCAppender 是利用传统的 JDBC 连接方法,这种方式连接数据库效率低下,为了解决这个问题,现在自定义一个 Log4j 的 Appender, ...

  9. Oracle Ebs R12 SLA与GL关系变化

    http://www.cnblogs.com/bruce_zhao/p/3809886.html Oracle Ebs R12 SLA与GL关系变化 SLA概念:SLA(Subledger Accou ...

  10. 如何使不同主机上的docker容器互相通信

    docker启动时,会在宿主主机上创建一个名为docker0的虚拟网络接口,默认选择172.17.42.1/16,一个16位的子网掩码给容器提供了65534个IP地址.docker0只是一个在绑定到这 ...