Android:如何取消回收者视图图像请求

时间:2016-08-10 08:27:57

标签: android

我正在使用recyclerView使用asysnc任务显示图像。我从Web服务器获取图像。我的代码是

从onBindViewHolder方法我调用

new ImageLoadTask(url, holder.imageView).execute();

我的ImageLoader asysnc任务是

public class ImageLoadTask extends AsyncTask<Void, Void, Bitmap> {

        private String url;
        private ImageView imageView;
        ProgressDialog pDialog;

        public ImageLoadTask(String url, ImageView imageView) {
            this.url = url;
            this.imageView = imageView;
        }

        @Override
        protected Bitmap doInBackground(Void... params) {
            try {
                URL urlConnection = new URL(url);
                HttpURLConnection connection = (HttpURLConnection) urlConnection
                        .openConnection();
                connection.setDoInput(true);
                connection.connect();

                InputStream input = connection.getInputStream();
                Bitmap myBitmap = BitmapFactory.decodeStream(input);
                return myBitmap;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            super.onPostExecute(result);
            imageView.setImageBitmap(result);
        }
    }

问题是当我在下载图像之前滚动并跳过一个或多个视图并且该视图被回收时,图像donwnload reqest在这些中间视图上没有被取消,导致那些/那些图像之前闪现在该视图中加载了实际图像。

我尝试从适配器传递HttpURLConnection并检查它是否为null,然后在disconnect方法之前调用onBindViewHolder,但仍然会发生。我正在使用

if (holder.urlConnection != null)
    {
        holder.urlConnection.disconnect();
        try {
            holder.urlConnection.getInputStream().close();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        holder.urlConnection = null;
    }

    new ImageLoadTask(url, holder.imageView,holder.viewHolderActivity, holder.urlConnection).execute();

如何取消图像请求?

4 个答案:

答案 0 :(得分:3)

保存

中的ImageLoadTask链接
    if (holder.urlConnection != null)
        {
            holder.urlConnection.disconnect();
            try {
                holder.urlConnection.getInputStream().close();
            }
            catch (Exception e) {
                e.printStackTrace();
            }
            holder.urlConnection = null;
        }

      holder.imageTask = new ImageLoadTask(url, holder.imageView,holder.viewHolderActivity, holder.urlConnection);
      holder.imageTask.execute();

并在

上取消
//Called when a view created by this adapter has been recycled.
public void onViewRecycled(VH holder){
      holder.imageTask.cancel();
}

答案 1 :(得分:1)

ViewHolder上保留对ImageLoadTask的引用。 在onBindViewHolder方法中,通过调用其ImageLoadTask方法取消现有cancel,并为新图像创建新任务。请注意,取消AsyncTask时,它不会调用onPostExecute方法,而是调用onCancelled

答案 2 :(得分:0)

尝试使用cancel()方法取消asynctask以取消图像请求:

ImageLoadTask imageLoadTask=new ImageLoadTask(url, holder.imageView);
imageLoadTask.cancel(true);

答案 3 :(得分:0)

使用滑行: https://inthecheesefactory.com/blog/get-to-know-glide-recommended-by-google/en

它是一个快速响应的框架,用于从任何给定的后端加载图像。你可以做像setTimeout,cancelRequests,fadeEffects和其他一些东西。您甚至不必担心如何处理网络请求。 Glide会为你做到这一点。

用法:

Glide.with(context)
  .load(imageLoadPath)
  .placeholder(imgToShowWhileLoading)
  .centerCrop()
  .into(imageView);

然后您可以像这样设置GlideModule配置: (原始代码段:glide image loading timeout increase)。创建一个自定义类来实现GlideModule。在其中一个最重要的方法中:

@Override
public void registerComponents(Context context, Glide glide) {
    final int retryPolicy = 10000;
    RequestQueue queue = new RequestQueue(
            new DiskBasedCache(new File(context.getCacheDir(), "volley")),
            new BasicNetwork(new HurlStack())) {
        @Override public <T> Request<T> add(Request<T> request) {
            request.setRetryPolicy(new DefaultRetryPolicy(retryPolicy, 1, 1);
            return super.add(request);
        }
    };
    queue.start();
    glide.register(GlideUrl.class, InputStream.class, new VolleyUrlLoader.Factory(queue));
}

播放超时限制,并了解它如何满足您的需求。