2013-03-25 87 views
0

我正在研究一個由不同屏幕組成的應用程序,我將其設計爲不同佈局的不同活動。對於每個屏幕,都有兩個大的(1536x2048)png文件,用作疊加背景(它們是alpha混合的)。目前,該活動的佈局XML文件是類似的東西:Android內存不足錯誤 - 爲什麼GC不起作用?

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:tools="http://schemas.android.com/tools" 
android:layout_width="match_parent" 
android:layout_height="match_parent" 
android:background="@drawable/backgroundPic0" 
tools:context=".TakvimActivity" > 

    <ImageView 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:background="@drawable/backgroundPic1" 
    /> 

</RelativeLayout> 

暫時,我能夠從主要活動前往三個不同的活動。我這樣做只是與

Intent intent = new Intent(this, TakvimActivity.class); 
    startActivity(intent); 

據我所知,背景圖像消耗每一個新的活動開始時間和setContentView方法被調用約24 MB的內存。當我第一次前往一個新屏幕時,返回到主屏幕並轉到另一個新的活動,由於內存不足異常,應用程序崩潰,並說「在blabla字節分配時內存不足」。 (請注意,它不會在第二個Activity轉換時完全崩潰,有時在第三個轉換時會崩潰)。在我看來,應用程序不會在從一個遊戲返回時釋放資源(最重要的是圖像文件)活動。我通過覆蓋onDestroy方法來檢查當前活動是否被正確銷燬,並且我看到它被正確調用。由於對其視圖層次的引用被擦除,GC不應該清除所有與UI相關的內存,因爲它正在被銷燬?是否有我缺少的東西,例如,是否有明確的方法來清除我沒有包含在我的代碼中的活動內存?

+2

AFAIK相似,但Android Studio中的重點問題,資源留在你的進程加載一次。您可能需要使用「BitmapFactory」明確地管理您的大圖像,而不是使用'android:background'',最好使用'inBitmap'和'BitmapFactory.Options'重複使用相同的'Bitmap'內存緩衝區。請記住,「內存不足」錯誤並不意味着你沒有堆空間,而是沒有足夠大的連續塊來滿足你的請求。Android的垃圾收集器是非壓縮的,所以你可以分割你的內存這樣你就不能加載大量的圖像,即使有大量的免費堆。 – CommonsWare 2013-03-25 15:07:59

+0

@CommonsWare這是否意味着每次我第一次啓動一個活動時,它使用的資源都會在應用程序的生命週期中分配並持續存在?明確的方式來加載它們之後刪除資源 – 2013-03-25 17:12:11

+1

「這是否意味着每次我第一次啓動一個活動時,它使用的資源在應用程序的整個生命週期內都被分配並保留下來?」 - AFAIK,它們是懶惰的 - 無論如何,一旦加載,它們就會保留在你的進程期間的內存中。請參閱http://stackoverflow.com/a/10135306/115145「是否有明確的方法來刪除資源,一旦它們是l是否已經?「 - 不是我所知道的。 – CommonsWare 2013-03-25 17:21:02

回答

0

嘗試添加下面的方法您的應用程序,並從你的活動將其稱爲例如:

private void unbindDrawables(View view) { 
    try 
    { 
     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(); 
      }   
     } 
    catch(Exception e) 
    { 
     e.printStackTrace();    
    } 

} 

@Override 
protected void onDestroy() 
{ 
super.onDestroy(); 
//R.id.LayoutId is the id of the root layout of your activity 
unbindDrawables(findViewById(R.id.LayoutId)); 
    System.gc(); 

} 
+0

我試過了,但應用程序仍然崩潰。似乎位圖文件不會被刪除。 – 2013-03-25 17:09:29