我們平時設置圖片的時候,幾乎都忘記回收老的(背景)圖片,比如:
- 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(); } }