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

时间:2018-03-19 13:16:20

标签: java android picasso android-glide

注意:此问题与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的图像请求?

3 个答案:

答案 0 :(得分:3)

取消图像请求的最佳方法是致电Glide.clear()
这是示例代码。

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

答案 1 :(得分:1)

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

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

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

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

答案 2 :(得分:1)

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

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

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

        //listener for keyboard show/hide
        [self setKeyboardListenersInRegisterView];
        [self.studentUsernameTextField becomeFirstResponder];
        [self.studentUsernameTextField addTarget:self.studentPasswordTextField action:@selector(becomeFirstResponder) forControlEvents:UIControlEventEditingDidEndOnExit];
    });

如果您坚持自己创建取消机制,请查看Glide如何在ListPreloader类中执行此操作。具体来说,他们使用requestManager来处理取消。以下是cancelAll的代码片段。

 * 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.

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