-
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
Glide doesn't show the latest image if its from the same URL #1847
Comments
@Parithi nice report/question! Re
|
Thanks a lot for the detailed help @TWiStErRob! Regarding your answers, I have a few doubts. Answer 1. My client's requirement is that I need to refresh the image immediately, so I can't have it to update once a day. Answer 2. I believe this is the solution I should be going with but I'm not able to understand how this works. In our app, we are currently using Okhttp 3. I looked up the classes at: https://github.com/bumptech/glide/tree/master/integration/okhttp3/src/main/java/com/bumptech/glide/integration/okhttp3 So, once I add the code below to my build.gradle, Glide will be making the requests using OkHttp 3.
From your answer,
I don't understand this part. From what I understand, Are you suggesting that I make changes to the Integration library files of Glide by performing the below? If I'm making the Image In order to accomplish this, I need to
or Without adding integration libraries to Glide, I could use just make an Okhttp HEAD request for the URL, and obtain the ETAG and use it as a signature for the Glide request. Would this be a better way of doing it? Answer 4. This solution was pretty obvious when I learnt about signature but My client doesn't/can't send me any kind of metadata, I have nothing but the static URL that doesn't change so I don't have any data to be used as a signature. Thanks a lot for helping me out. |
You're likely thinking too low level, you probably don't even need to do an actual HEAD, sorry if I misled you there. dependencies {
compile 'com.github.bumptech.glide:okhttp3-integration:1.4.0@aar'
} public class CustomOkHttpGlideModule implements GlideModule {
@Override public void applyOptions(Context context, GlideBuilder builder) {}
@Override public void registerComponents(Context context, Glide glide) {
OkHttpClient client = new OkHttpClient.Builder()
// do some OkHttp 3 magic here to handle ETags (can't help you here, sorry)
.build();
glide.register(GlideUrl.class, InputStream.class, new OkHttpUrlLoader.Factory(client));
}
} <meta-data android:name="your.package.CustomOkHttpGlideModule" android:value="GlideModule" />
<meta-data android:name="com.bumptech.glide.integration.okhttp3.OkHttpGlideModule" tools:node="remove" /> Glide.with(this).load("http://parithinetwork.com/test.jpg").diskCacheStrategy(NONE).into(imageView); I suggest using Stetho, Wireshark or other advanced logging mechanism to your requests hitting the OkHttp cache.
I hope that allows for "keep the same image during a session", otherwise you need to turn off memory caching as well, which would be very unfortunate.
That would also work as well, but as far as I know the above solution would work with one request instead of two per load. |
Thanks for the great help @TWiStErRob! I'll try it out :) Please do consider integrating this directly into the next version of glide, if you think it would be a valuable addition. Thanks again! |
@TWiStErRob sorry for re-opening such an old issue, but I have a question on your idea:
DiskCacheStrategy.NONE leads to have none image cached, even if the etag is not changed. This is how I have it implemented without glide:
This way, I have only 1 call, with either no data (304) or directly the data I can use (200). So, back to glide: even if I add eTag to a DataFetcher, what shall I do then if I get 304 back? I only have callback.onDataReady() and callback.onDataFailed(). |
If the fetcher is called it's too late to decide about caching. Fetcher fetches the data when it wasn't cached. You can disable caching in Glide and enable it in OkHttp (handling E-Tags), so it'll always call the fetcher, but OkHttp will use its own disk cache to respond. |
This is how I solved it:
This way, I can use glide with eTags and glides internal caching system and "any" network library. |
@tobiasKaminsky How do you deal with disk caching when you use the |
I am always querying with if-none-match to get the latest etag. |
@TWiStErRob thanks for the pointers 1,2,3,4 above and sorry for reopening it again. I'm curious about last 4th option where you asked about to add signature api.
Now problem it, it still taking images from DATA_DISK_CACHE even after modified image.. I try by adding |
Is it possible to force remote request after 'x' mins/hrs/days without invalidating disk cache? |
@imspatni I think my answer is for v3, you're probably on v4, hence deprecation @imspatni @rakesh-mohan the disk cache will contain the old image (if it was there), the whole question is when to invalidate, so I'm not sure I understand how you want to not invalidate. I can imagine something like this: val time = System.currentTimeMillis()
Glide
.with(this)
.load(thing.url)
.signature(ObjectKey(time / 24*60*60*1000))
.thumbnail(Glide
.with(this)
.load(thing.url)
.signature(ObjectKey(thing.lastRequestTimeStamp / 24*60*60*1000))
.preventNetworkLoad() // not sure about the v4 API, in v3 it was not that bad
)
.into(...)
thing.lastRequestTimeStamp = time // this needs to be persisted for *each* of your things that have the image |
@TWiStErRob Thanks much! This is the expected solution. It works 💯 . |
@TWiStErRob sorry for re-opening such an old issue, and I also face the same problem:
And for better performance and user experience, I also want to use cache. So is there any way to get the image first, and then check its metadata like image last modified time or md5 to decide update ImageView or not. Thanks a lot Finally, I find a solution: #527 (comment) |
@taichushouwang If I understand right, the workaround you mention is for a webcam image: they always want to reload a new image. They use the previous cached image as a placeholder, but always fetch a new image as well. About the scenario when users can switch avatars as many times as they want, this isn't quite the same as a webcam. If a user didn't change their avatar, the client shouldn't reload a new one. I'm looking for a solution to load a new image when it's available, without loading a new image when it's not necessary 🤔 |
Hi,
I could find that this issue has been reported by a few others but I would like to have a clearer solution for this. I'm new to Glide. Kindly bear with me.
Issue :
I'm loading an image from the server where the image will get updated with the same url in a listview. Glide is showing the old cached image even if the image has been updated from the server.
Things I've read and tried:
How I need to solve it:
I would like to send a request to the image URL, obtain the headers first, check if the timestamp/etag from the header request are different from the cached local copy. If they are different, send a request again to obtain the full image data and update the cache.
Does the signature() api follow this method internally within Glide? If not, which classes do I need to change by forking the library in order to accomplish my goal.
Code used :
Glide.with(this).load("http://parithinetwork.com/test.jpg").into(imageView);
Glide Version: 3.7.0
Integration libraries: None
Device/Android Version: Xperia Z2(6.0.1), Samsung S3 (4.1)
The text was updated successfully, but these errors were encountered: