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

问题描述 投票:2回答:2

注意:这个问题与this问题不同,因为没有给出问题的答案解释如何取消我们为预装图像做出的图像请求。

我有一个无限的名单(RecyclerView)。我需要从RecyclerView的最后一个绑定项目预加载下一个'x'(读取3)项目的图像。此外,当特定的Viewholder与窗口分离时,如果已经不成功,我需要取消预加载图像请求。

我通过以下方式实现了它。

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

我能够达到预期的效果。但我正面临这种方法的记忆问题。如果我不使用预加载,我的内存使用量在150-200 MB之间。但是,如果我开始使用预加载,内存使用量将跃升至250-300 mb。在进行堆转储之后,如果我不使用预加载,我会看到很多Bitmap对象不存在(没有那么多)。

那么在Glide中预加载图像的最佳方法是什么?我还可以在将来取消图像请求?如果我不使用SimpleTarget,有没有办法取消仅基于imageUrl的图像请求?

java android picasso android-glide
2个回答
1
投票

使用预加载方法将图像加载到内存缓存中:

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

您可以稍后使用缓存的图像:

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

1
投票

在您的情况下,您应该将ListPreloader与RecyclerViewPreloader结合使用,而不是一次预加载一个项目,RecyclerViewPreloader一次处理一批。

请参阅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.

如果你坚持自己创建一个取消机制,那么看看Glide如何在他们的ListPreloader类中做到这一点。具体来说,他们使用requestManager来处理取消。以下是cancelAll的代码片段。

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

PreloadTargetQueue是该文件中的自定义内部类。

© www.soinside.com 2019 - 2024. All rights reserved.