Android Listview GC_FOR_ALLOC释放:DDMS android.graphics.Bitmap

时间:2014-06-02 13:44:05

标签: android android-listview garbage-collection ddms

我在android中遇到了listview的问题。当我开始向下滚动列表时,它非常慢,我看到GC被调用。当我在列表的底部时,一切都很顺利。我认为,此时我的ViewHolder可以完成这项工作。

但我无法找到调用GC的来源。我搜索了哪些导致:

DDMS     436816    byte[]   1   android.graphics.Bitmap    nativeCreate 

我不能解释那条线。我的ArrayAdapter及其getView方法如下所示:

 public class DiagnoseAdapter extends ArrayAdapter<Visualizer> {
   @Override
   public View getView(int position, View convertView, ViewGroup parent) {

    int type = TYPE_DEFAULT;
    final Visualizer item = getItem(position);

    switch(item.getType()){
         case TYPE_DEFAULT:
                convertView = DefaultTextView.getView(position, convertView, mlayoutInflater, item, parent);
            break;

     // more cases/types

    }
  return convertView;
  }
}

正在调用类getView

的以下DefaultTextView方法
public class DefaultTextView{

 public static View getView(int position, View convertView, LayoutInflater layoutInflater, Visualizer item, ViewGroup parent){
    ViewHolder holder;
    if (convertView == null || item.getReleatedObject() == null || convertView.getTag()!=TAG_DEFAULT) {  

     convertView = layoutInflater.inflate(R.layout.diagnose_item, null);

     holder = new ViewHolder();

     holder.value = (TextView) convertView.findViewById(R.id.diagnose_function_value);
     holder.name = (TextView) convertView.findViewById(R.id.diagnose_function_setname);
     holder.mLinLayout = (LinearLayout) convertView.findViewById(R.id.default_linlayout);

     convertView.setTag(TAG_DEFAULT);
     convertView.setTag(R.layout.diagnose_item,holder);
     item.setReleatedObject(convertView);

    } else {

    holder = (ViewHolder) convertView.getTag(R.layout.diagnose_item);

    }

    holder.value.setText(item.toString());
    holder.name.setText(item.getToolTip());


        holder.mLinLayout.removeAllViews();
         if (item.getUpdateFlag(4)) {
             if (holder.back == null){
                holder.back = new ImageView(convertView.getContext());
                holder.back.setScaleType(ScaleType.FIT_CENTER);
                holder.back.setAdjustViewBounds(true);
                holder.back.setImageBitmap(bm1);
             }
             holder.mLinLayout.addView(holder.back);
         } 

        if (item.getUpdateFlag(1)) {
             if (holder.update == null){
                    holder.update = new ImageView(convertView.getContext());
                    holder.update.setScaleType(ScaleType.FIT_CENTER);
                    holder.update.setAdjustViewBounds(true);
                    holder.update.setImageBitmap(bm2);

                 }
             holder.mLinLayout.addView(holder.update);
        } 

        if (item.getUpdateFlag(2)) {
            if (holder.timer == null){
                holder.timer = new ImageView(convertView.getContext());
                holder.timer.setScaleType(ScaleType.FIT_CENTER);
                holder.timer.setAdjustViewBounds(true);
                holder.timer.setImageBitmap(bm3)

             }
            holder.mLinLayout.addView(holder.timer);
        } 

        if (item.getUpdateFlag(3)) {
            if (holder.log == null){
                holder.log = new ImageView(convertView.getContext());
                holder.log.setScaleType(ScaleType.FIT_CENTER);
                holder.log.setAdjustViewBounds(true);
                holder.log.setImageBitmap(bm4);

             }
            holder.mLinLayout.addView(holder.log);
        }

        if (item.getUpdateFlag(0)) {
            if (holder.forward == null){
                holder.forward = new ImageView(convertView.getContext());
                holder.forward.setScaleType(ScaleType.FIT_CENTER);
                holder.forward.setAdjustViewBounds(true);
                holder.forward.setImageBitmap(bm5);

             }
            holder.mLinLayout.addView(holder.forward);
        }

    return convertView;
}

static class ViewHolder {            
    TextView name, value;            
    ImageView back, update, timer, log, forward;
    LinearLayout mLinLayout;
} 

}

即使我对LinearLayout发表评论,我也只有一个包含两个TextViews的列表。

所以我的问题。我什么都错过了。有些蠢事吗?如何让ListView更流畅? 顺便说一句:我在另一个帖子中读到,如果ListView具有属性android:cacheColorHint="#00000000,则会发生这种情况。我没有这个属性。

我希望有人有解决方案。谢谢!

2 个答案:

答案 0 :(得分:0)

关于GC来电的来源。如果我正确理解您的代码,每次回收ListView项目并调用removeAllViews()时,都会删除先前动态创建的ImageView,并对其Bitmap进行垃圾回收。因此,如果您在xml布局中使用相同的ImageView声明它,并根据您的Bitmap替换getUpdateFlag(),也许可以避免那些GC调用。

关于ListViews和Images的另外两件事。首先,如果图像太大,无论如何,ListView都会变得迟钝。如果是这种情况,您需要缩小图像(Loading Large Bitmaps Efficiently)。第二,也许你还需要实现一个Lazy List,它按需加载图像,有一个着名的问题 - &gt; How do I do a lazy load of images in ListView?

答案 1 :(得分:0)

我终于解决了我的问题。像上面一样,我认为问题是基于我的列表项的图像。但那不是问题。我没有正确使用我的ViewHoldersgetItemViewType(int position)方法。我有一个包含许多不同项目布局的列表,我看到,我上面的代码为每个项目创建了一个新的convertView和一个新的ViewHolder,这不应该是。我找到了一个关于如何使用多项布局的精彩教程(参见下面的链接):

Multiple List Item Layouts