Xonal
Xonal

Reputation: 1360

Android - Unknown memory leak in a very light app

I'm writing a very simple "contacts" application. For now, I just have a ListView and next to each name is an image. There are only 20 contacts and each image averages about 4.5kb, so there's no way I should be reaching the app's memory limit upon starting it. I'm not sure where the issue is, but I'm guessing it's in the code that generates the rows.

public View getView(int position, View convertView, ViewGroup parent) {
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    View row = inflater.inflate(R.layout.single_row, parent, false);
    TextView name = (TextView) row.findViewById(R.id.topLine);
    TextView phone = (TextView) row.findViewById(R.id.secondLine);
    ImageView icon = (ImageView) row.findViewById(R.id.icon);

    name.setText(contactArray.get(position).getName());
    phone.setText((CharSequence) contactArray.get(position).getPhone().getWorkPhone());
    new ImageDownloader(icon).execute(contactArray.get(position).getImageURL());

    return row;
}

The problem will go away if I comment out the to lines relating to my ImageView. Why would those lines take up more memory than necessary?

Upvotes: 0

Views: 165

Answers (1)

Philippe A
Philippe A

Reputation: 1252

You are inflating an xml layout for each view instead of recycling existing views. Inflating a layout is an expensive operation (in memory) so you could start there.

public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
    convertView = mInflater.inflate(R.layout.your_layout, null);
}

TextView text = (TextView) convertView.findViewById(R.id.text);
text.setText("Position " + position);

return convertView;

}

Then use the ViewHolder pattern

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

    if (convertView == null) {
        convertView = mInflater.inflate(R.layout.your_layout, null);

        holder = new ViewHolder();
        holder.text = (TextView) convertView.findViewById(R.id.text);

        convertView.setTag(holder);
    } else {
        holder = convertView.getTag();
    }

    holder.text.setText("Position " + position);

    return convertView;
}

private static class ViewHolder {
    public TextView text;
}

Source: http://lucasr.org/2012/04/05/performance-tips-for-androids-listview/

Upvotes: 2

Related Questions