Как отменить выполнение AsyncTask из скрытого элемента в функции getView() в Android?

У меня проблема: в функции getView() ArrayAdapter я выполняю загрузку изображения в ImageView с помощью AsyncTask. Но когда этот элемент невидим (просмотр списка прокрутки), функция AsyncTask по-прежнему загружает изображение. Я хочу отключить процесс AsyncTask, если элемент невидим. Есть решение для этой проблемы?

5 ответов

Это будет включать два этапа.

1) Поймите, что представление элемента прокрутилось за пределы экрана (или больше не будет использоваться по другой причине).

Вы можете установить использование setRecyclerListener() добавить RecyclerListener объект, который будет уведомлен всякий раз, когда представление элемента собирается быть переработанным (onMovedToScrapHeap()).

2) На самом деле прервать AsyncTask.

Это зависит от того, что вы на самом деле делаете внутри. Если выполняется HTTP-запрос (как видно из описания), то вызов cancel(true) должно вызвать прерывание и прервать загрузку.

Однако перед всем этим подумайте: если изображение загружалось, и вы прерываете этот процесс, это означает, что его, вероятно, придется загружать снова при прокрутке вверх. Возможно, лучшей стратегией будет просто позволить завершить загрузку, но не загружать ImageView сам он был повторно использован (что вы можете обнаружить, установив для него метку).

Если вы не используете RecyclerViews, вы также можете сделать следующее в getView()

        if(vH.thumb.getTag() != null)
            ((LoadImage) vH.thumb.getTag()).cancel(true);
        LoadImage loadImage =  new LoadImage(vH.thumb, context.getActivity());
        loadImage.execute(pic);
        vH.thumb.setTag(loadImage);

Поэтому вы должны работать с ViewHolder(=vH). Это очень полезно, если вы загружаете изображения, где вы можете отменить саму загрузку. Спрашивая isCancelled() Вы сейчас, когда остановиться.

Я знаю, что это старый вопрос, но это решение мне очень помогло.

Вы можете использовать метод cancel(true) и проверить с помощью isCancelled(), была ли задача отменена.

Проверьте документацию http://developer.android.com/reference/android/os/AsyncTask.html

Вы можете проверить, когда изображение загружено, если это все еще правильный элемент ListView, где он должен отображаться. Как описано в этом ответе, сначала сохраните путь в качестве тега ImageView и отметьте onPostExecute:

protected void onPostExecute(Bitmap result) {
    if (!imv.getTag().toString().equals(path)) {
           /* The path is not same. This means that this
              image view is handled by some other async task. 
              We don't do anything and return. */
           return;
    }

    if(result != null && imv != null){
        imv.setVisibility(View.VISIBLE);
        imv.setImageBitmap(result);
    }else{
        imv.setVisibility(View.GONE);
    }
}

Растровое изображение все равно будет загружено полностью.

Используйте Universal Image Loader. В подобных сборках я использую

displayImage(URL, imageview);

Функция этой библиотеки в getView. Изображения отображаются при заданном просмотре изображений, и это довольно быстро. Вы также можете уменьшить размер изображения для более быстрой загрузки. Библиотека также избавит вас от большой работы и выполнения / отслеживания множества асинктических задач.

Другие вопросы по тегам