0

I am using an AsyncTask to lazy load images in my ListView.

This all works correctly, but I do not understand why I have to check my mHolder.hPosition vs the mPosition in the onPostExecute method. If I don't check these values, I'll get old images cycling through incorrect ListItems - but why are mHolder.hPosition and mPosition not always equal if they are being called in the same AsyncTask ?

Here is my trimmed-down code:

 @Override
    public View getItemView(final int position, View convertView, final ViewGroup parent) {

        final ViewHolder holder;
        final Job job = (Job) getStore().get(position);

        if (convertView == null) {

            // New List Item

            holder = new ViewHolder();
            convertView = getInflater().inflate(ITEM_LAYOUT, parent, false);

            holder.hPosition = position;
            holder.hImageView = (ImageView) convertView.findViewById(R.id.app_component_joblistitemview_logo);

            convertView.setTag(holder);

        } else {

            // Recycled List Item

            holder = (ViewHolder) convertView.getTag(); // get the ViewHolder that is stored in the Tag
            holder.hPosition = position;
        }

        holder.hImageView.setImageBitmap(null); // set the list item's image to be blank
        new DownloadImageTask().execute(position, holder); // async download the image

        return convertView;
    }


    // DownloadImageTask
    private class DownloadImageTask extends AsyncTask<Object, Void, Integer> {

        Integer mPosition;
        ViewHolder mHolder;

        @Override
        protected Integer doInBackground(Object... params) {

            mPosition = (Integer)params[0];
            mHolder = (ViewHolder)params[1];

            // Download the Image ...

            // ...

            return 1;
        }

        protected void onPostExecute(Integer result) {

            // >> This is the Spot I am Asking About <<
            // Shouldn't mHolder.hPosition ALWAYS be equal to mPosition, since it's still the same AsyncTask?
            // Why are mHolder.hPosition and mPosition often not equal?

            if (mHolder.hPosition==mPosition) {

                // ... update the List View Item

            }
        }

    }
Chris
  • 5,485
  • 15
  • 68
  • 130
  • because your holder can be reused at time image downloaded – Leonidos Dec 12 '14 at 16:06
  • So is it not creating a new/local instance of mHolder each time a new AsyncTask is started? Should I not be using values from the holder inside AsyncTask because they could change as I scroll through the list? – Chris Dec 12 '14 at 16:09

1 Answers1

2

While you download the image, you can continue scroll the list view.

ViewHolder can be recycled and can have another data in this moment.

To check if ViewHolder is in correct position, you should check if the actual position on holder is the same position that generated the download event on onPostExecute.

Mou
  • 2,027
  • 1
  • 18
  • 29