bumptech / glide

An image loading and caching library for Android focused on smooth scrolling
https://bumptech.github.io/glide/
Other
34.65k stars 6.12k forks source link

How to clear cache #624

Closed nvhaiwork closed 9 years ago

nvhaiwork commented 9 years ago

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

TWiStErRob commented 9 years ago
nvhaiwork commented 9 years ago

"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 commented 9 years ago

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 commented 9 years ago

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 commented 9 years ago

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 commented 9 years ago

image was not refreshed

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

nvhaiwork commented 9 years ago

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 commented 9 years ago

Do you use an integration library?

nvhaiwork commented 9 years ago

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 commented 9 years ago

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 commented 9 years ago
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 commented 9 years ago

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 commented 9 years ago

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 commented 9 years ago

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 commented 9 years ago

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

nvhaiwork commented 9 years ago

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 commented 9 years ago

Let's invoke @sjudd!

sjudd commented 9 years ago

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 commented 9 years ago

@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 commented 9 years ago

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 commented 9 years ago

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

maximeloridan commented 9 years ago

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: https://github.com/bumptech/glide/issues/678

ghost commented 8 years ago

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

TWiStErRob commented 8 years ago

@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 commented 8 years ago

However I use clearCache but it does not work for me

champrocks3190 commented 7 years ago

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 commented 7 years ago

I met the same problem and got the answers from the comments. Thank you :+1:

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

@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 commented 7 years ago

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

jp1017 commented 5 years ago
StringSignature

where's StringSignature?

TWiStErRob commented 5 years ago

@jp1017 https://github.com/bumptech/glide/issues/2692