-
Notifications
You must be signed in to change notification settings - Fork 6.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update cache / force to load via network #463
Comments
The API doesn't directly support this use case, but you can probably get what you want using the thumbnail and signature APIs. You can use an incrementing number as your signature and save the value for the last successful fetch in a database or shared preferences. Then you load your last known good value as your thumbnail, and the same request with an incremented value as the full request. The thumbnail will load the image from cache and display it, then the full request will fetch the image, cache it again, and replace the thumbnail. You can either use a custom Target or a RequestListener to save the incremented value when the full request completes. Your request might look something like this: Glide.with(fragment)
.load(url)
.signature(new StringSignature(lastKnownGoodValue + 1))
.thumbnail(
Glide.with(fragment)
.load(url)
.signature(new StringSignature(lastKnownGoodValue)))
.into(imageView); Thumbnails are loaded with higher priority, but only displayed until their parent completes, at which point they are replaced by the result of the parent load (if it is successful). For what it's worth, this is somewhat wasteful. If you have control over your backend, it might be more performant to make a separate metadata only request for the state of your urls rather than downloading the images each time. |
Just throwing things out there. @zasunkx It should also be possible to somehow harness HTTP 304 Not Modified, if your server supports it. It may require you to write a clever model/decoder/cache. @sjudd Would it be possible to support 304 inside the stock decoder and/or as a feature to allow generic external (over the wire) "Did this resource change?" questions? I guess the problem is that the decoder is not even consulted becuse we have the resource in cache, but there's no expiry for it, because it's LRU. This may sound like an async signature.... |
I really don't know how Glide handle caching of Images Cache-Control: private, max-age=0, no-cache Date:serverDate You can define max age in Header , so next time Glide should check validate and update accordingly , and if the server return 304 then Glide should pick from device cache or else update it . Volley has better managed HTTP caching .I have not looked into Glide Implementation thought Glide support Volley Integration as well |
@vipinhelloindia I think this is close to what I asked sjudd if it's possible to incorporate this in a generic way. Currently you have to do it yourself as described above. Also my understanding is that Glide uses the image in cache if it's cache key is matched, otherwise not. As far as I know there's no internal handling of those HTTP headers. You can set cache-control all you like, but once an image gets into Glide's cache, it'll reuse it. Glide won't even attempt to connect to the endpoint again (i.e. won't call DataFetcher methods) like a browser would to revalidate if the cached file is not too old. However the cache key is a really dynamic thing with fine control over what it will become in the end and there are ways around this. Some time ago in one of the issues it was stated that Glide is an image loading library not a networking library. You can howerer replace the networking part via integration libraries. If you think Volley has what you need, you can try setting up that as a cache and disabling Glide's cache (DiskCacheStrategy.NONE), but this needs some evaluation of priorities and side effects, proceed with much caution. |
@TWiStErRob Sorry I missed your comment earlier. If you want http caching, you can absolutely use Volley, HttpUrlConnection, or OkHttp with caching and use DiskCacheStrategy.NONE in Glide. You could even probably find a way to build this in using the interfaces Glide provides, although I'm not sure there's a clean way to do so. If you do come up with a way to implement this, I'd definitely consider a contribution. That said, as @TWiStErRob mentioned, Glide is an image loading library. I'm trying to do my best to avoid building a network library underneath, especially because there are so many good alternatives. From a more philosophical perspective, I also have a hard time believing that relying on http caching or 304s provides a great experience for users. My understanding here might be flawed, but it seems that relying on 304s gives you two bad options:
In the first case you're taking a decode time that usually takes milliseconds or tens of milliseconds and subjecting it to an RPC that may take hundreds or thousands of milliseconds. Ideally you use unique urls for each image and use separate RPCs or GCM messages to notify the app when those images/urls change. |
@sjudd, completely different seems a little stretch. I would imagine that having the same url would at least relate to the displayed entity in some way and would be completely different all the time. I could think of these two use cases where this would be helpful:
|
I see the point, but ultimately if you want http caching, you should use an http library. We've tried to make it super simple to integrate nicely with pretty much any networking library you can think of. Volley in particular implements http caching and we have a fairly robust default implementation for it. I'm definitely open to ideas that make caching more robust, or integrating with libraries easier (ie setting a default disk cache strategy). |
I have constant ImageURLs in my application with changing content (Bitmaps) but the client doesn't know when those images are updated. Now, I want those images to load the following way:
Desired effect:
Case 1 - the content of mImageURL didn't change since last download: The image is displayed immediately (step 1) and is replaced by an updated version later (step 3), but as both images are identical the replacement won't be noticable.
Case 2 - the content of mImageURL did change: At first the old image (step 1) pops up, but after the cache was updated it is replaced by the new image a little later (step 3).
How can I achieve this?
I tried to implement step 2 with .downloadOnly() as I thought that would enforce loading from network, but apparently it didn't. The FutureTarget contained the same old bitmap as in step 1 although the content of mImageURL changed. I didn't find any other way to explicity load from network (but save in cache), nor to invalidate the cache of an url. I couldn't think of a way signatures could solve my problem either.
The text was updated successfully, but these errors were encountered: