like some others before me (#509), i'm wondering if there can be a method such as
DiskCacheUtils.findInCache(url)
the problem i'm currently facing is this:
the same image has different urls based on the size we want to retrieve:
for example:
image.jpg?w=360 and image.jpg?w=720
so when going from a feed where the smaller image is displayed to a detailed view where we want to display the larger image, we want to first see if the larger image is already cached. if it is not, then we grab the smaller image instead since we know it has already been loaded and cached. if the larger image has been cached because the user accessed it somewhere else, then we can just load the large image instead
This sounds an awful lot like #712, whose solution is based on #639.
You need to enable SOURCE cache (or ALL) so you have the original image saved in disk cache. This is needed to load even the smaller image as thumbnail and then later as detail. With the default RESULT cache you you'd need to use override and others to exactly match the load when loaded as thumbnail.
Let me know what you think about those solutions.
From Custom Cache Invalidation:
Since it's often difficult or impossible to change identifiers, Glide also offers the signature() API to mix in additional data that you control into your cache key. Signatures work well for media store content, as well as any content you can maintain some versioning metadata for.
sorry for the lag in this @TWiStErRob , but going back to this problem, if i had two images
image.jpg?w=360 and image.jpg?w=720, and i set my diskCacheStrategy to DiskCacheStretegy.SOURCE, would there be two images in the cache? or would there be just one due to the same base url.
my concern right now is if i did something like
Glide.with(view.getContext())
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.override(targetDimensions[0], targetDimensions[1])
.thumbnail(
Glide.with(view.getContext())
.load(imageUrlThumbnail)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.override(targetDimensions[0], targetDimensions[1]
.into(view.getImageView());
i would be unnecessarily getting and storing imageUrlThumbnail, thus caching double the images, half of which the user may never even need.
i've tried changing the diskCacheStretegy to NONE for the thumbnail, but that ended up not working for me as I still see placeholders instead of loaded images when it should have been loaded
No probs, it's you who needs a solution ;)
It would be unnecessarily getting and storing imageUrlThumbnail [...] never even need.
In the original description you already highly likely had imageUrlThumbnail in cache because you're coming from the feed. It is true though, both will be stored in SOURCE cache. The user will see the LQ image fast and then a moment later it will clear up with the code you showed.
Also if it's impossible for the HQ image to be in cache it's not even worth dealing with this issue. So it must be possible, which means that HQ image is used somewhere else in the application, hence downloading both of the images is not a waste. It's proactively caching for that other use case. It's not optimal though.
Please note that you missed the most important part of #712:
.using(new NetworkDisablingLoader())
which will prevent downloading the non-cached HQ image. Also make sure that there is a potential point in the application where imageUrl is loaded with SOURCE/ALL cache, otherwise it will never hit.
Here's another type of solution that may interest you (I wrote it before I realized it's not necessarily helpful; so I just leave it here):
class Item { String baseUrl; ... }
// GlideModule
glide.register(Item.class, InputStream.class, new ItemLoader.Factory());
// load
Glide.with(context).load(new Item("image.jpg")).diskCacheStrategy(SOURCE).into(imageView);
// glue
class ItemLoader extends BaseGlideUrlLoader<Item> {
public ItemLoader(Context context) { super(context); }
@Override protected String getUrl(Item model, int width, int height) {
return model.baseUrl + "?w=" + bucket(width, height);
}
private int bucket(int width, int height) {
int bucket = width / 360;
bucket = Math.max(1, Math.min(2, bucket)); // get it between 1 and 2 by clamping
return bucket * 360;
}
static class Factory extends ModelLoaderFactory<Item, InputStream> { ... }
}
This lets Glide figure out which image is needed for a certain target. Though this won't fall back. It's good for bucketing per device. Even this solution stores both resolutions if the view (or .override) sizes vary much.
I assume you managed to make it work based on the silence.
Most helpful comment
I assume you managed to make it work based on the silence.