【Android开发坑系列】之常常被忽略的背景图片内存泄露

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

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

这样形成内存浪费,聚沙成塔,整个软件可能浪费很多内存。spa

若是记得优化,整个软件的内存占用会有10%~20%的降低。code

// 得到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();
}

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

封装以下(仅针对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();
    }
}
相关文章
相关标签/搜索