2010-01-15 44 views
5

我有一個包含圖像圖標(存儲在drawables文件夾中)的70個文本項目的列表。 如果我第一次啓動應用程序並緩慢滾動列表 - 不會發生異常。滾動圖像列表時出現OutOfMemory異常

當應用程序被啓動的第一時間,我滾動與「甩」動作列表中出現以下異常:

java.lang.OutOfMemoryError: bitmap size exceeds VM budget 
at android.graphics.BitmapFactory.nativeDecodeAsset(Native Method) 
at android.graphics.BitmapFactory.decodeStream(BitmapFactory.java:439) 
at android.graphics.BitmapFactory.decodeResourceStream(BitmapFactory.java:322) 
at android.graphics.drawable.Drawable.createFromResourceStream(Drawable.java:688) 
at android.content.res.Resources.loadDrawable(Resources.java:1710) 
at android.content.res.Resources.getDrawable(Resources.java:585) 

之後,如果我殺死DDMS的應用程序,再次和滾動啓動它與'一擲'動作,異常不會發生。因此,只有在第一次安裝和啓動應用程序時纔會出現異常情況。

這裏是我使用的列表中選擇適配器:

public class AuthorAdapter extends ArrayAdapter<Author> { 

private ArrayList<Author> items; 
private Context context; 
private LayoutInflater inflater; 

public AuthorAdapter(Context context, int textViewResourceId, ArrayList<Author> items) { 
    super(context, textViewResourceId, items); 
    this.items = items; 
    this.context = context; 
    inflater = LayoutInflater.from(this.context); 
} 

static class ViewHolder { 
    ImageView authorFace; 
    TextView authorName; 
    TextView authorWho; 
} 

@Override 
public View getView(int position, View convertView, ViewGroup parent) { 

    ViewHolder holder; 

    if (convertView == null) { 
     convertView = inflater.inflate(R.layout.autor_data, null); 

     holder = new ViewHolder(); 
     holder.authorFace = (ImageView) convertView.findViewById(R.id.authorFaceImageView); 
     holder.authorName = (TextView) convertView.findViewById(R.id.authorNameTextView); 
     holder.authorWho = (TextView) convertView.findViewById(R.id.authorWhoTextView); 
     convertView.setTag(holder); 
    } else { 
     holder = (ViewHolder) convertView.getTag(); 
    } 

    Author author = items.get(position); 
    if (author != null) { 
     if (holder.authorFace != null) { 
      String faceFileName = author.getFace(); 
      String facePlaceName = context.getPackageName() + ":drawable/" + faceFileName.subSequence(0, faceFileName.lastIndexOf(".")); 
      int faceFileId = context.getResources().getIdentifier(facePlaceName, null, null); 
      holder.authorFace.setImageResource(faceFileId); 
     } 
     if (holder.authorName != null) { 
      holder.authorName.setText(author.getName()); 
     } 
     if (holder.authorWho != null) { 
      holder.authorWho.setText(author.getWho()); 
     } 
    } 
    return convertView; 
} 

}

有沒有辦法避免的異常? 我應該捕捉異常並以某種方式逃離內存嗎?

任何建議如何做到這一點?

謝謝。

+0

您的圖片有多大 – 2010-01-15 15:01:46

+0

列表項圖片大小約爲3KB。我使用兩個活動(主要和列表)。活動背景圖像每個大約60KB。還有我用於UI控件的圖像,總共大約100 KB。它可能是一個模擬器問題? 不幸的是,我現在無法在設備上試用我的應用程序。 – Zzokk 2010-01-18 07:09:50

回答

3

你不能趕上java.lang.OutOfMemoryError。他們非常致命。

現在,你說這個問題只發生在你第一次運行你的應用程序。這使我認爲問題不是與視圖代碼。如果用戶使用大量資源瀏覽資源,它可能會佔用大量內存,但正如您所說,通常您的應用程序可以正常工作。

那麼 - 您在第一次運行應用程序時做了什麼初始化?首次運行一次的任務是否有可能泄漏內存,意味着沒有足夠的剩餘空間來使用您的視圖?

+0

實際上,當我第一次啓動應用程序時,我不會初始化任何圖像。我所有的圖像都存儲在drawables文件夾中。我只爲該列表設置適配器。在適配器的getView()方法中,我爲每個列表項設置圖像(請參閱上面的代碼): holder.authorFace.setImageResource(faceFileId); 據我所知getView()方法每次在手機屏幕上顯示一個列表項。可能當我快速滾動列表時,緩存沒有時間回收。 當我慢慢地滾動列表時,沒有觀察到異常。 – Zzokk 2010-01-15 10:23:05

+2

我想知道是否有一些其他的初始化行爲正在泄漏內存,所以當你快速滾動視圖時,堆上沒有空間存儲大量圖像。這可以解釋爲什麼只有在您第一次運行應用程序時纔會出現問題。 – 2010-01-15 10:44:47

+1

同意戴夫,我會開始看你在做什麼,你第一次啓動應用程序與正常啓動。在應用程序的第一次初始化期間,您會抓住一些重要的東西。 – 2010-01-15 15:10:03