简体   繁体   English

Android - 使用Glide库预加载图片时如何取消图片请求?

[英]Android - How to cancel the image request when preloading images with the Glide library?

Note: This question is different from this question as no answers given for the question explain how to cancel the image request which we make for preloaded image.注意:这个问题与这个问题不同,因为这个问题没有给出答案来解释如何取消我们对预加载图像的图像请求。

I have an infinite list( RecyclerView ).我有一个无限列表( RecyclerView )。 I need to preload images of next 'x'(read 3) items from the last bound item of the RecyclerView .我需要从RecyclerView的最后一个绑定项目中预加载下一个“x”(读取 3)个项目的图像。 Also, when a particular Viewholder is detached from the window, I need to cancel the preload image request if it is already not successful.此外,当特定的Viewholder从窗口分离时,如果它已经不成功,我需要取消预加载图像请求。

I have achieved it in the following way.我通过以下方式实现了它。

Map<Integer, SimpleTarget> simpleTargetMap = new HashMap<>();

public void preloadImage(int position, Context context, String imageUrl) {
    SimpleTarget simpleTarget = new SimpleTarget() {
      @Override
      public void onResourceReady(@NonNull Object resource, @Nullable Transition transition) {
        simpleTargetMap.remove(position);
      }
    };
    Glide.with(context)asBitmap().load(imageUrl).into(simpleTarget);
    simpleTargetMap.put(position, simpleTarget);
}


  @Override
public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) {
    super.onViewDetachedFromWindow(holder);
    SimpleTarget simpleTarget = simpleTargetMap.get(holder.getAdapterPosition());
    Glide.with(context).clear(simpleTarget);
    simpleTargetMap.remove(holder.getAdapterPosition());
}

I am able to achieve the desired result.我能够达到预期的结果。 But I am facing memory issues with this approach.但我面临着这种方法的记忆问题。 If I don't use the preloading, my memory usage is between 150-200 mb.如果我不使用预加载,我的内存使用量在 150-200 MB 之间。 But if I start using the preload, the memory usage jumps to 250-300 mb.但是,如果我开始使用预加载,内存使用量会跃升至 250-300 MB。 After taking a heap dump, I see a lot of Bitmap objects which are not there(not as many) if I don't use preload.在进行堆转储后,如果我不使用预加载,我会看到很多不存在的位图对象(没有那么多)。

So what is the best way to preload an image in Glide where I can also cancel the image request in the future?那么在 Glide 中预加载图像的最佳方式是什么,我也可以在将来取消图像请求? And if I don't use SimpleTarget, is there any way of cancelling an image request based only of the imageUrl?如果我不使用 SimpleTarget,是否有任何方法可以取消仅基于 imageUrl 的图像请求?

Best way to cancel the image request is to call Glide.clear()取消图像请求的最佳方式是调用Glide.clear()
Here is the sample code.这是示例代码。

 Glide.with(context).clear(imageviewRef);

In your case, instead of preloading one item at a time, you should be using ListPreloader in conjunction with the RecyclerViewPreloader which handles the loading one batch at a time.在您的情况下,您应该将 ListPreloader 与 RecyclerViewPreloader 结合使用,而不是一次预加载一个项目,后者一次处理一批加载。

Refer to https://github.com/bumptech/glide/blob/master/library/src/main/java/com/bumptech/glide/ListPreloader.java and https://github.com/bumptech/glide/blob/master/integration/recyclerview/src/main/java/com/bumptech/glide/integration/recyclerview/RecyclerViewPreloader.java参考https://github.com/bumptech/glide/blob/master/library/src/main/java/com/bumptech/glide/ListPreloader.javahttps://github.com/bumptech/glide/blob/ master/integration/recyclerview/src/main/java/com/bumptech/glide/integration/recyclerview/RecyclerViewPreloader.java

 * Loads a few resources ahead in the direction of scrolling in any {@link AbsListView} so that
 * images are in the memory cache just before the corresponding view in created in the list. Gives
 * the appearance of an infinitely large image cache, depending on scrolling speed, cpu speed, and
 * cache size.

If you are adamant about creating a cancel mechanism yourself, then look at how Glide do it in their ListPreloader class.如果您坚持要自己创建一个取消机制,那么看看 Glide 如何在他们的 ListPreloader 类中做到这一点。 Specifically they use a requestManager to handle the cancelling.具体来说,他们使用 requestManager 来处理取消。 Below is their code snippet for cancelAll.下面是他们的 cancelAll 代码片段。

private void cancelAll() {
    for (int i = 0; i < maxPreload; i++) {
      requestManager.clear(preloadTargetQueue.next(0, 0));
    }
  }

PreloadTargetQueue is a custom inner class in that file. PreloadTargetQueue 是该文件中的自定义内部类。

Load images into memory cache using preload method:使用 preload 方法将图像加载到内存缓存中:

Glide.with(context)
        .load(url)
        .preload(500, 500);

You can later use the cached images using:您稍后可以使用缓存的图像:

Glide.with(yourFragment)
    .load(yourUrl)
    .into(yourView);

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

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