Skip to content
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

How to clear cache #624

Closed
nvhaiwork opened this issue Sep 14, 2015 · 31 comments
Closed

How to clear cache #624

nvhaiwork opened this issue Sep 14, 2015 · 31 comments
Labels

Comments

@nvhaiwork
Copy link

Hi,
How can I clear Glide's cache in case.

  • Clear all cache
  • Clear cache of an URL.
@TWiStErRob
Copy link
Collaborator

  • Call Glide.get(context).clearDiskCache() on outside the UI thread. (also consider clearMemory() too to prevent surprises after clearing disk cache)
  • Read Cache invalidation, because it's not otherwise possible to remove a single file from cache, see How to clear or reload an image in cache #94 for arguments. If you explain your "Clear cache of an URL" use case we may be able to give a better suggestion.

@nvhaiwork
Copy link
Author

"Clear cache of an URL".
I have an Image to display user's profile image.
Then after user changes his(her) profile image I want to refresh to display the new uploaded image.

@TWiStErRob
Copy link
Collaborator

Yep, then .signature() is your best friend. Save the latest upload time to the profile image along with the image and use something like:

.load(profile.imageUrl)
.signature(new StringSignature(profile.imageLastUpdate))

@nvhaiwork
Copy link
Author

Thanks for you support.
One more question, is there any other solution incase I do not have "profileLastUpdate".
Just have image' url only. And I want to cache an image until new update

@TWiStErRob
Copy link
Collaborator

Options:

  1. You can use the file's lastModified time if you can modify the server response

  2. Use a regular interval like daily or weekly: that is the signature changes every day:

    .signature(new StringSignature(System.currentTimeMillis() / (24 * 60 * 60 * 1000)))
  3. Store the profile update yourself in the app, but this doesn't work if you display other people's profile, because then you'd need to sync the DBs which is much more cumbersome then modifying the way the app receives the profile url.

@TWiStErRob
Copy link
Collaborator

image was not refreshed

you also need to reload the image using the usual Glide.with.load.into after the clears finish.

@nvhaiwork
Copy link
Author

I already used cleardiskcache but image was not refreshed.
My code:

boolean isSuccess = new UserApi().doUploadImage(mUser.getId().getOid(), strUploadType);
            if (isSuccess) {
                Glide.get(getActivity()).clearDiskCache();
                Glide.get(getActivity()).clearMemory();
            }

Then :

Glide.with(ctx).load(strProfileUrl).dontAnimate().placeholder(R.mipmap.ic_launcher).into(imvProfile);

But no luck

@TWiStErRob
Copy link
Collaborator

Do you use an integration library?

@nvhaiwork
Copy link
Author

I'm not sure what is "integration library"
But I'm using

compile 'com.github.bumptech.glide:glide:3.6.1'

for import library. I'm new to Glide :D

@TWiStErRob
Copy link
Collaborator

https://github.com/bumptech/glide/wiki/Integration-Libraries
I was asking because there may be a caching issue somewhere in the pipeline. The server can cache the response (return old profile image for a while even after update), a proxy can cache the response, the networking library on the client (in this case android app) can cache and finally Glide can cache (this is what you surely fixed with .clear*).
Make sure the Glide.with.load.into is called after, because they're run on different threads. into is called on UI thread and clears must be on background threads.

@nvhaiwork
Copy link
Author

private class UploadImageAsyncTask extends AsyncTask {

    @Override
    protected void onPreExecute() {
        super.onPreExecute();

    }

    @Override
    protected Boolean doInBackground(Void... voids) {


        boolean isSuccess = upload api;
        if (isSuccess) {

            Glide.get(getActivity()).clearDiskCache();
            Glide.get(getActivity()).clearMemory();
        }

        return isSuccess;
    }

    @Override
    protected void onPostExecute(Boolean aBoolean) {
        super.onPostExecute(aBoolean);

        if (aBoolean) {
               // Url
           Glide.with(fragment).load(strCoverUrl).dontAnimate().placeholder(R.drawable.img_splash_bg).into(imvCover);
           }
     }
}

Sure load image after clear cache.
The image just refreshed if I force close my app(close app by 'recent view').

@TWiStErRob
Copy link
Collaborator

How do you load it normally when you first show the fragment?
Also the line is commented out, I hope it's not like that in your running code ;)

@nvhaiwork
Copy link
Author

How do you load it normally when you first show the fragment?

Glide.with(fragment).load(strCoverUrl).dontAnimate().placeholder(R.drawable.img_splash_bg).into(imvCover);

Also the line is commented out, I hope it's not like that in your running code ;)
=> Sure :D

@TWiStErRob
Copy link
Collaborator

Hmm, maybe Glide checks if the new load is any different than the currently loaded image and ignores the new one if the same. I can't back this up with code though.

You could try calling Glide.clear(imvCover) in onPostExecute -> if (aBoolean) { just before the load and see if that helps. The image will probably flash the placeholder as usual. As a workaround for the flash you can also try:

Drawable oldImage = imvCover.getDrawable(); // may be unsafe
Glide.clear(imvCover); // force Glide to forget about anything related to this view
Glide.with(fragment).load(strCoverUrl).dontAnimate().placeholder(oldImage).into(imvCover);

Before you try this I suggest you add .listeners, logging the arguments to LogCat, to all loads into imvCover to see what's going on, maybe there's a hidden exception there.

Sorry for the hacky workarounds, I can't come up with other ideas yet.

@nvhaiwork
Copy link
Author

Thanks for your help.
I need to go out now, I'll try and let you know the result.
Thanks :D

@nvhaiwork
Copy link
Author

Debugged

@Override
public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target,
        boolean isFromMemoryCache, boolean isFirstResource) {
    return false;
}

and saw that: isFromMemoryCache = true even cache is cleared before.
Hummmmm

@TWiStErRob
Copy link
Collaborator

Let's invoke @sjudd!

@sjudd
Copy link
Collaborator

sjudd commented Sep 15, 2015

Is the resource you're about to reload already being displayed in a View or Target? If so, it may be loaded from active resources, which is checked prior to the caches.

If you want to change the user's profile picture and reload it, either change the url when the the profile picture changes, or use the .signature() API and some kind of version key identifying the particular version of the profile photo. Using the signature API is described in the wiki.

@nvhaiwork
Copy link
Author

@sjudd : Thanks for your suggestion, I solved it my problem with .signature.
But I still worrying about cache problem that noticed above. I already called clearDiskCache and memoryCache but the image was still loaded from cache

@TWiStErRob
Copy link
Collaborator

It's not loaded from disk or memory cache, it's loaded from active resources, which are the images currently showing in views. Since nothing has changed according to Glide (i.e. cache key) it assumes that the current image is the same as what you're loading. Clearing the cache is a brute force method which is not advised, especially because only one image changed. Using .signature() should solve the problem by itself without clearing anything; use it for both initial and after-change load.

@sjudd sjudd added the question label Sep 15, 2015
@sjudd
Copy link
Collaborator

sjudd commented Sep 15, 2015

Yup, signature is a much better solution. Let us know if you have any other questions.

@maximeloridan
Copy link

Hello,
I had the same problem, so I read carefully all this post.
I wanted to implement the signature method, but it does not work on my phone.
Here's a new issue for my question: #678

@ghost
Copy link

ghost commented May 23, 2016

I think that should use clearMemory() and clearDiskCache() together ......

@TWiStErRob
Copy link
Collaborator

@kimgod can you please elaborate on that? What are you responding to?
(Note: in general you shouldn't ever call those methods during normal app operation)

@CoXier
Copy link

CoXier commented Sep 29, 2016

However I use clearCache but it does not work for me

@champrocks3190
Copy link

ok solved ,:) i put pth of image as signature at the end 👍 at the time of change image(gallery intent) i store path of image in sharedprefs and using sharedpref everywhere i want to update image , it will download image once after image updated as like profile picture and then will use cache instead load everytime as the problem in system.currenttimemillis i dont know is it proper approach but dont find any solution for cache

SharedPreferences prefs =getActivity().getSharedPreferences("your_prefs", Activity.MODE_PRIVATE);
String pathx = prefs.getString("password",null);

if (pathx==null){
    pathx="wow";
}

Toast.makeText(getContext(),"getedshare"+pathx,Toast.LENGTH_LONG).show();

Glide.with(this)
        .using(new FirebaseImageLoader())
        .load(st)
        .signature(new StringSignature(pathx))
        .into(fragcm);

//get the path of image u selected in gallery intent , in string from shared prefs in the onactivityresult and done

@amazingguni
Copy link

I met the same problem and got the answers from the comments. Thank you 👍

Glide.with(context).load(Uri.parse(userProfile.getProfileImageUri()))
                                .signature(new StringSignature(Long.toString(System.currentTimeMillis()))).centerCrop()
                                .into(profileImageImageView);

@TWiStErRob
Copy link
Collaborator

@amazingguni that's not right... whatever your goal is. Any time you load the image it'll be cached in a separate file using a lot of network, CPU and disk space.

It essentially turns off caching, you should use .diskCacheStrategy(NONE) to do that, this removes the disk pressure from the picture. If you want to force loads in the same session to refresh the profile image as well you can also add .skipMemoryCache(). I really think you should consider dividing the millis with an interval of invalidation, even if it's just a few hours. Consider that the common thing to happen is to have the same profile image for years.

@amazingguni
Copy link

I'll try to use skipMemoryCache(), after changing profile image. Thank you for your kind explanation.

@jp1017
Copy link

jp1017 commented Mar 19, 2019

StringSignature

where's StringSignature?

@TWiStErRob
Copy link
Collaborator

@jp1017 #2692

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

8 participants