简体   繁体   English

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

[英]Android: How to cancell recycler view image request

I am using a recyclerView to show images using asysnc task. 我正在使用recyclerView使用asysnc任务显示图像。 I am getting the images from a web server. 我正在从Web服务器获取图像。 My code is 我的代码是

from onBindViewHolder methode I call 从onBindViewHolder方法调用

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

My ImageLoader asysnc task is 我的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);
        }
    }

The problem is when I scroll and skip one or more views before the image is downloaded and that view is recycled the image donwnload reqest is not canceled on those intermediate view resulting in a flash of that/those image(s) before the actual image is loaded in that view. 问题是当我在下载图像之前滚动并跳过一个或多个视图并且该视图被回收时,那些中间视图上的图像下载请求未取消,从而导致该/那些图像在实际图像被刷新之前就闪烁了。在该视图中加载。

I tried passing the HttpURLConnection from the adapter and checking if its not null and then calling disconnect on this as shown before from onBindViewHolder methode, but still it happens. 我尝试从适配器传递HttpURLConnection并检查其是否不为null,然后像以前从onBindViewHolder方法中所示那样对此disconnect ,但是仍然会发生。 I am using the 我正在使用

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();

What can I do to cancel the image requests ? 如何取消图像请求?

Save ImageLoadTask link in holder 将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();

and cancel it on 并取消

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

On your ViewHolder keep a reference to your ImageLoadTask . ViewHolder保留对ImageLoadTask的引用。 in the onBindViewHolder method cancel the existing ImageLoadTask by calling its cancel method and create a new task for the new image. onBindViewHolder方法取消现有ImageLoadTask通过调用其cancel方法,并创建新的图像的新任务。 Note that when a AsyncTask is cancelled it will not call the onPostExecute method instead it will call onCancelled . 需要注意的是,当一个的AsyncTask被取消也不会调用onPostExecute方法来代替它会调用onCancelled

Try to cancel asynctask using cancel() method in order to cancel the image request: 尝试使用cancel()方法取消asynctask以取消图像请求:

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

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

It's a fast and responsive framework for loading images from any given back-end. 这是一个快速响应的框架,用于从任何给定的后端加载图像。 You can do stuff like setTimeout, cancelRequests, fadeEffects and some other stuff. 您可以做诸如setTimeout,cancelRequests,fadeEffects之类的事情。 You don't even have to worry about how to handle the network request. 您甚至不必担心如何处理网络请求。 Glide will simply do that for you. Glide会为您轻松做到这一点。

Usage: 用法:

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

And then you can set the GlideModule configuration like this: (Original code snippet: glide image loading timeout increase ). 然后,您可以像这样设置GlideModule配置:(原始代码段: glide图片加载超时增加 )。 Make a custom class to implement GlideModule. 创建一个自定义类以实现GlideModule。 In one of it's overriding methods: 在其中一种最重要的方法中:

@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));
}

Play with timeout limit all you want, and see how it can meet your needs. 发挥超时限制,尽情享受,并了解它如何满足您的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM