简体   繁体   English

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

[英]Android Listview GC_FOR_ALLOC freed: DDMS android.graphics.Bitmap

I'm having trouble with a listview in android. 我在android中使用listview遇到麻烦。 When I start scrolling down my List, it is very slow and I see that the GC is called. 当我开始向下滚动列表时,它非常慢,并且看到GC被调用。 When I'm at the bottom of my List, everything works fine and smooth. 当我排在列表的底部时,一切都会顺利进行。 I think that at this point my ViewHolder does the work. 我认为这时我的ViewHolder就可以了。

But I can't find the source that is calling the GC. 但是我找不到调用GC的源。 I searched which lead to: 我搜索了导致:

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

I can't interpret that line. 我无法解释那条线。 My ArrayAdapter and it's getView method looks like this: 我的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;
  }
}

which is calling the following getView Method of the class DefaultTextView 它正在调用以下类的DefaultTextView getView方法

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;
} 

}

Even if I comment the LinearLayout out, so I just have a List with two TextViews . 即使我将LinearLayout注释掉,我也只有一个带有两个TextViews的List。

So my Question. 所以我的问题。 Do I miss anything. 我想念什么吗? Some stupid thing? 一些愚蠢的事情? How do I get my ListView smoother? 如何使我的ListView更流畅? BTW: I read in a different thread, that it is happening if the ListView has the attribute android:cacheColorHint="#00000000 . I don't have this attribute. 顺便说一句:我读到一个不同的线程,如果ListView具有android:cacheColorHint="#00000000 。我没有此属性。

I hope anyone has a solution. 我希望任何人都有解决方案。 Thanks! 谢谢!

About the source of GC calls. 关于GC调用的来源。 If I'm understanding your code correctly, everytime your ListView items are recycled and you call removeAllViews() , a previously dynamically created ImageView is removed and its Bitmap is garbage collected. 如果我正确理解您的代码,则每次回收ListView项目并调用removeAllViews() ,都会删除以前动态创建的ImageView并将其Bitmap进行垃圾回收。 So, Maybe those GC calls would be avoided if you use the same ImageView declaring it in your xml layout and just replace the Bitmap according to your getUpdateFlag() . 因此,如果您使用相同的ImageView在xml布局中声明它,并且仅根据getUpdateFlag()替换Bitmap ,也许可以避免那些GC调用。

And two more things about ListViews and Images. 还有关于ListViews和Images的两件事。 First thing is that if the image is too big, your ListView is going to be laggy no matter what. 第一件事是,如果图像太大,无论如何,您的ListView都会变得迟钝。 You would need to scale the image down if that is the case( Loading Large Bitmaps Efficiently ). 在这种情况下,您需要按比例缩小图像( 有效地加载大位图 )。 And second, maybe you would also need to implement a Lazy List, which loads images on demand, there is a famous question about that --> How do I do a lazy load of images in ListView? 其次,也许您还需要实现一个懒惰列表,该懒惰列表按需加载图像,对此有一个著名的问题-> 如何在ListView中进行图像的延迟加载?

I've finally solved my Problem. 我终于解决了我的问题。 Like above, I thought the problem was based on the images of my list items. 像上面一样,我认为问题出在我列表项的图像上。 But that wasn't the problem. 但这不是问题。 I just didn't use my ViewHolders and the getItemViewType(int position) method correctly. 我只是没有正确使用ViewHoldersgetItemViewType(int position)方法。 I have a list with many different item layouts and I saw, that my code above created a new convertView and a new ViewHolder for every single item, which wasn't supposed to be. 我有一个列表,其中包含许多不同的项目布局,并且我看到,上面的代码为每个项目创建了一个新的convertView和一个新的ViewHolder,这是不应该的。 I found a great tutorial about how to use multiple item layouts (see link below): 我找到了一个很棒的教程,介绍如何使用多个项目布局(请参见下面的链接):

Multiple List Item Layouts 多个列表项布局

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM