【Android開發坑系列】之經常被忽略的背景圖片內存泄露


我們平時設置圖片的時候,幾乎都忘記回收老的(背景)圖片,比如:

  • 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();
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM