2012-09-12 50 views
6

我正在使用圖像設置爲我所有活動的背景,但它導致內存溢出問題並導致應用程序崩潰。現在,我在我的活動中暫停()和Destroy()上解除綁定,現在它顯示按下後退按鈕上的空白屏幕。那麼如何避免使用額外內存呢?Unbinding drawables onPause()導致無響應的後退導航並跳過此步驟導致內存溢出

protected void onPause(){ 
    super.onPause(); 
    unbindDrawables(findViewById(R.id.login_root)); 
} 

protected void onDestroy() { 
     unbindDrawables(findViewById(R.id.login_root)); 
     super.onDestroy(); 
     } 

private void unbindDrawables(View view) { 
    System.gc(); 
    Runtime.getRuntime().gc(); 
    if (view.getBackground() != null) { 
    view.getBackground().setCallback(null); 
    } 
    if (view instanceof ViewGroup) { 
     for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
     unbindDrawables(((ViewGroup) view).getChildAt(i)); 
     } 
    ((ViewGroup) view).removeAllViews(); 
    } 

起初,我在不斷膨脹採用了android我的佈局:背景=「@繪製/」總是造成內存溢出錯誤,指出VM不會讓我們分配10MB現在,我從得到一個位圖(應用程序)。該drawable沒有縮小和綁定它在運行時。現在它說VM不會讓我們分配5MB(應用程序),而不使用unbindDrawables(..) 顯然背景圖像質量顯示已經下降,但我不能瞭解如果我使用的是13KB的png文件,那麼JVM如何處理請求需要5或10MB空間?

我已經將我的佈局語句從onCreate()轉換爲onResume()方法,但應用程序在按下後退按鈕時再次用完內存。

public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
    } 

    protected void onResume(){ 
     setContentView(R.layout.home); 
     Bitmap bmp; 
     ImageView background = (ImageView)findViewById(R.id.iv_home_background); 
     InputStream is = getResources().openRawResource(R.drawable.background); 
     bmp = BitmapFactory.decodeStream(is); 
     background.setImageBitmap(bmp); 

     super.onResume(); 
    } 

protected void onPause(){ 
     super.onPause(); 
     unbindDrawables(findViewById(R.id.home_root)); 
    } 


private void unbindDrawables(View view) { 
     System.gc(); 
     Runtime.getRuntime().gc(); 
     if (view.getBackground() != null) { 
     view.getBackground().setCallback(null); 
     } 
     if (view instanceof ViewGroup) { 
      for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { 
      unbindDrawables(((ViewGroup) view).getChildAt(i)); 
      } 
     ((ViewGroup) view).removeAllViews(); 
     } 
    } 
+0

請記住,如果onDestroy()被調用,之前也調用onPause()。 –

+0

僅在'onPause()'解綁定,如@JohnSatriano所述。但仍然,請向我們展示您的onResume函數 –

+0

我沒有覆蓋我的Resume函數。我完全不知道該怎麼做。 – Atinder

回答

1

我找到了解決此問題的方法。現在我將運行時的位圖縮放到非常小的尺寸,然後將它們存儲在內部存儲器中。該程序在運行時從存儲調用縮放的位圖,如果它不存在,它將從可繪製文件夾調用它,縮放它,將其寫入存儲器,然後將其綁定到視圖。 以這種方式,無需在任何時間點調用unbindDrawables方法,並且應用程序始終保持響應。 我現在唯一關心的是位圖的質量,我認爲我需要在縮放尺寸方面進行嘗試,以最大限度地提高可能的尺寸。

0

您正在爲每個子視圖調用GC。嘗試只在所有解除綁定完成後調用一次。

unbindDrawables(findViewById(R.id.login_root)); 
System.gc(); 

GC是一個沉重的負載,它太頻繁地調用它是無用的。事實上,如果沒有泄漏,它應該是nesesary。

還要記住,png文件大小與內存位圖無關。這裏有更多的信息 http://developer.android.com/training/displaying-bitmaps/index.html