Использование Custom Adapter использует больше оперативной памяти? - PullRequest
3 голосов
/ 01 июля 2011

мое приложение на первом обеде использует 6,5 МБ, а затем, когда я вхожу в занятие с 3 вкладками, с вкладкой, которая отображает просмотр списка, оно использует 14 МБ !!

Это произошло, когда я перешел от «плохого кода» с SimpleAdapter к своему пользовательскому адаптеру.

То, что я хочу, - это две строки с каждой стороны в списке. Строки находятся в массиве, вот как я говорил, люди говорили мне, что это неправильный способ:

String[] array= getResources().getStringArray(R.array.Names_List);

int lengthtmp= array.length;
for(int i=0;i<lengthtmp;i++)
{
    counter++;
    AddToList(array[i]);            
}

adapter = new SimpleAdapter(this,list,R.layout.start_row,new String[] {"number","suraname"},new int[] {R.id.Start_Numbering,R.id.Start_Name});


private void AddToList(String name) {
HashMap<String,String> temp = new HashMap<String,String>();


temp.put("number", Integer.toString(SortingPictures[counter-1]));

temp.put("suraname", name);
list.add(temp);

  }

С этим кодом активность занимает 10 МБ ОЗУ. После изменения моего кода для использования пользовательского адаптера он использует 14 МБ:

 public class ListView_Start_Adapter extends BaseAdapter{
private String[] SuraNames;
private int[] PageNumber;
private Context mContext;
RelativeLayout relativeView;
TextView tv_SuraName;
TextView tv_PageNumber;
RelativeLayout.LayoutParams param;

public ListView_Start_Adapter(Context context, String[] SuraNames, int[] PageNumber){
    mContext=context;
    this.SuraNames=SuraNames;
    this.PageNumber=PageNumber;
}

@Override
public int getCount() {
    // TODO Auto-generated method stub
    return SuraNames.length;
}

@Override
public Object getItem(int arg0) {
    // TODO Auto-generated method stub
    return SuraNames[arg0];
}

@Override
public long getItemId(int arg0) {
    // TODO Auto-generated method stub
    return PageNumber[arg0];
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // TODO Auto-generated method stub
    relativeView= new RelativeLayout(mContext);
    tv_SuraName = new TextView(mContext);
    tv_PageNumber = new TextView(mContext);

    tv_SuraName.setText(SuraNames[position]);
    tv_PageNumber.setText(Integer.toString(PageNumber[position]));

    param = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
    param.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);

    relativeView.addView(tv_SuraName, param);
    relativeView.addView(tv_PageNumber);

    return relativeView;

}

  }

Может кто-нибудь сказать мне, почему так много оперативной памяти используется при использовании нестандартного адаптера? Что-то не так с этим нестандартным адаптером?

РЕДАКТИРОВАТЬ1: Это лучший код, который предложил Дзиобас:

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

    if(convertView == null) {
        convertView = mInflater.inflate(R.layout.start_row, parent,false);
        holder=new ViewHolder();

        holder.tv_SuraName   =(TextView)convertView.findViewById(R.id.Start_Name);
        holder.tv_PageNumber = (TextView)convertView.findViewById(R.id.Start_Numbering);
        convertView.setTag(holder);
    } else {
        holder  = (ViewHolder) convertView.getTag();
    }

    holder.tv_SuraName.setText(SuraNames[position]);
    holder.tv_PageNumber.setText(Integer.toString(PageNumber[position]));

    return convertView;
}

Я получаю ExceptionNullPointer в этой строке: "convertView = mInflater.inflate (R.layout.start_row, parent, false); "Почему?

Ответы [ 3 ]

3 голосов
/ 01 июля 2011

Вы не перерабатываете представление в getView.

Это будет намного лучше, как это:

public class ListView_Start_Adapter extends BaseAdapter {
    private String[]            SuraNames;
    private int[]               PageNumber;
    RelativeLayout.LayoutParams param;
    Context                     mContext;

    public ListView_Start_Adapter(Context context, String[] SuraNames, int[] PageNumber) {
        mContext        = context;
        this.SuraNames  = SuraNames;
        this.PageNumber = PageNumber;
        param           = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
        param.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
    }

    @Override
    public int getCount() {
        return SuraNames.length;
    }

    @Override
    public Object getItem(int arg0) {
        return SuraNames[arg0];
    }

    @Override
    public long getItemId(int arg0) {
        return PageNumber[arg0];
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder     holder;
        RelativeLayout rowView;

        if(convertView == null) {
            //create view
            rowView              = new RelativeLayout(mContext);
            holder               = new ViewHolder();
            holder.tv_SuraName   = new TextView(mContext);
            holder.tv_PageNumber = new TextView(mContext);
            rowView.addView(holder.tv_SuraName, param);
            rowView.addView(holder.tv_PageNumber);
            rowView.setTag(holder);
        } else {
            //recycle view
            rowView = (RelativeLayout) convertView;
            holder  = (ViewHolder) convertView.getTag();
        }

        //fill views
        holder.tv_SuraName.setText(SuraNames[position]);
        holder.tv_PageNumber.setText(Integer.toString(PageNumber[position]));

        return rowView;
    }

    class ViewHolder {
        RelativeLayout relativeView;
        TextView       tv_SuraName;
        TextView       tv_PageNumber;
    }
}

И измените создание представления.Используйте LayoutInflater и используйте XML для макета.

См. эту презентацию для получения дополнительной информации об эффективности адаптера списка.

2 голосов
/ 01 июля 2011

Не генерировать элемент пользовательского интерфейса для каждой записи

Вы возвращаете свежий относительный вид для каждой записи. Это будет

  1. Используйте больше памяти
  2. Давить больше на сборщик мусора

Используйте обычный способ реализации getView

// In the class
private LayoutInflater inflater;

// in the constructor
    inflater = (LayoutInflater)
        context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

// getView()
    if (view == null) {
        view = inflater.inflate(R.layout.element_layout, parent, false);
    }

Доступен исходный код SimpleAdapter

Просто посмотрите на SimpleAdapter.java . Исходный код находится в свободном доступе. Почти каждый адаптер имеет этот блок кода.

Счастливого взлома!

0 голосов
/ 01 июля 2011

Первое, что вы можете сделать, - это начать использовать convertView, переданный в getView, вместо создания новых представлений.В результате вы получите более высокую производительность (благодаря меньшему количеству сборщиков мусора и меньшему количеству построений представлений) и, возможно, меньшему использованию памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...