1

ListView包含相當多的項目(20個或更多),並且它們中的每一個都是帶有位圖源的ImageView。這些位圖不被壓縮,尺寸大約爲640x480。當剛加載ListView時,需要一些內存,但如果我滾動它,則可能會發生錯誤"Memory exceed VM budjet"。當我用另一個片段替換片段時,ListView仍然掛在內存中。我如何清除內存/ ListView緩存?ListView的內容佔用大量內存

更新:在一個單獨的線程

SimpleCursorAdapter.ViewBinder viewBinder = new SimpleCursorAdapter.ViewBinder() { 
     public boolean setViewValue(View view, Cursor cursor, int columnIndex) { 
      if (columnIndex == 0) { 
       TextView tv1 = (TextView) view; 
       if (cursor.getInt(4) == 0) 
        tv1.setTextColor(Color.GRAY); 
       else 
        tv1.setTextColor(Color.parseColor("#191919")); 
       tv1.setText(cursor.getString(columnIndex)); 
      } 
      if (columnIndex == 3) { 
       TextView tv1 = (TextView) view; 
       tv1.setText(cursor.getString(columnIndex)); 
      } 
      if (columnIndex == 2) { 
       final ImageView image = (ImageView) view; 
       Bitmap cachedImage = null; 
       try { 
        cachedImage = imageThreadLoader.loadImage(cursor.getString(columnIndex), new ImageThreadLoader.ImageLoadedListener() { 
         public void imageLoaded(Bitmap imageBitmap) { 
          image.setImageBitmap((Bitmap) new SoftReference(imageBitmap).get()); 
         } 
        }); 
       } catch (MalformedURLException mue) { 
        Log.e("Feeds fragment", "Can't load image"); 
       } 
       if (cachedImage != null) { 
        image.setImageBitmap(cachedImage); 
       } else image.setImageDrawable(getResources().getDrawable(R.drawable.icon)); 
      } 

圖片負荷:

我使用SimpleCursorAdapterViewBinder

+0

可能是你的listview不回收視圖 – ingsaurabh

+0

你是什麼意思?也許 – LackOfKnowledge

+0

我的意思是默認回收視圖的高效內存使用情況,如果你可以發佈你的getview方法,這會讓事情更加清晰 – ingsaurabh

回答

2

構建這樣的列表視圖使您自定義適配器,並將其設置到ListView

public class InteractiveArrayAdapter extends ArrayAdapter<Model> { 

    private final List<Model> list; 
    private final Activity context; 

    public InteractiveArrayAdapter(Activity context, List<Model> list) { 
     super(context, R.layout.main, list); 
     this.context = context; 
     this.list = list; 
    } 

    static class ViewHolder { 
     protected TextView text; 
     protected CheckBox checkbox; 
    } 

    @Override 
    public View getView(int position, View convertView, ViewGroup parent) { 
     View view = null; 
     if (convertView == null) { 
      LayoutInflater inflator = context.getLayoutInflater(); 
      view = inflator.inflate(R.layout.main, null); 
      final ViewHolder viewHolder = new ViewHolder(); 
      viewHolder.text = (TextView) view.findViewById(R.id.listitem_text); 
      viewHolder.checkbox = (CheckBox) view.findViewById(R.id.checkBox1); 
      viewHolder.checkbox 
        .setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { 

         public void onCheckedChanged(CompoundButton buttonView, 
           boolean isChecked) { 
          Model element = (Model) viewHolder.checkbox 
            .getTag(); 
          element.setSelected(buttonView.isChecked()); 

         } 
        }); 
      view.setTag(viewHolder); 
      viewHolder.checkbox.setTag(list.get(position)); 
     } else { 
      view = convertView; 
      ((ViewHolder) view.getTag()).checkbox.setTag(list.get(position)); 
     } 
     ViewHolder holder = (ViewHolder) view.getTag(); 
     holder.text.setText(list.get(position).getName()); 
     holder.checkbox.setChecked(list.get(position).isSelected()); 
     return view; 
    } 
} 

嘗試這種方式,你的不必要的視圖將被回收和excecution將更快,希望你將擺脫錯誤

+0

我必須清除這個適配器onDestroyView? – LackOfKnowledge

+0

如果我使用你的,我將不得不將位圖的列表放在適配器的構造函數中,並且它將以ram的形式存儲在fragment的所有生命週期中,但是當我看到必要時我想從外部存儲器中將圖像加載到內存中列表項,當它消失的時候卸載位圖(當我滾動列表時) – LackOfKnowledge

+0

對不起,我還沒有做過類似的事情,直到yet ..但我會給它一個嘗試..讓你知道我是否找到任何方式.. – MKJParekh

3

我建議您觀看關於ListViews的Google IO presentation。它包含了內存保存技術,它幫助我理解了ListView的邏輯。

+0

我'稍後再看 – LackOfKnowledge