簡體   English   中英

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

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

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

它正在調用以下類的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;
} 

}

即使我將LinearLayout注釋掉,我也只有一個帶有兩個TextViews的List。

所以我的問題。 我想念什么嗎? 一些愚蠢的事情? 如何使我的ListView更流暢? 順便說一句:我讀到一個不同的線程,如果ListView具有android:cacheColorHint="#00000000 。我沒有此屬性。

我希望任何人都有解決方案。 謝謝!

關於GC調用的來源。 如果我正確理解您的代碼,則每次回收ListView項目並調用removeAllViews() ,都會刪除以前動態創建的ImageView並將其Bitmap進行垃圾回收。 因此,如果您使用相同的ImageView在xml布局中聲明它,並且僅根據getUpdateFlag()替換Bitmap ,也許可以避免那些GC調用。

還有關於ListViews和Images的兩件事。 第一件事是,如果圖像太大,無論如何,您的ListView都會變得遲鈍。 在這種情況下,您需要按比例縮小圖像( 有效地加載大位圖 )。 其次,也許您還需要實現一個懶惰列表,該懶惰列表按需加載圖像,對此有一個著名的問題-> 如何在ListView中進行圖像的延遲加載?

我終於解決了我的問題。 像上面一樣,我認為問題出在我列表項的圖像上。 但這不是問題。 我只是沒有正確使用ViewHoldersgetItemViewType(int position)方法。 我有一個列表,其中包含許多不同的項目布局,並且我看到,上面的代碼為每個項目創建了一個新的convertView和一個新的ViewHolder,這是不應該的。 我找到了一個很棒的教程,介紹如何使用多個項目布局(請參見下面的鏈接):

多個列表項布局

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM