I am using Glide 3.8.0 in Android to prefetch the images:
Glide.with(context)
.load(imageUrl)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.preload();
With this I see the log that shows key with resolution [-2147483648x-2147483648]
V/Engine: Started new load in 1.75375ms, key: EngineKey{https://....com/uu/api/res/1.2/15USE5cHzsN75A26JngW_Q--/YXBwaWQ9eXRhY2h5b247Zmk9c3RyaW07aD0zNjA7dz02NDA7/http://....com/c026d208260f1b9d6880604661897d28+com.bumptech.glide.signature.EmptySignature#1341382+[-2147483648x-2147483648]+''+'ImageVideoBitmapDecoder.com.bumptech.glide.load.resource.bitmap'+''+'BitmapEncoder.com.bumptech.glide.load.resource.bitmap'+'GifBitmapWrapperDrawableTranscoder.com.bumptech.glide.load.resource.transcode'+''}
And when loading the actual image view, lookup is done with different size [1224x1020]:
V/Engine: Started new load in 0.45197899999999996ms, key: EngineKey{https://....com/uu/api/res/1.2/15USE5cHzsN75A26JngW_Q--/YXBwaWQ9eXRhY2h5b247Zmk9c3RyaW07aD0zNjA7dz02NDA7/http://....com/c026d208260f1b9d6880604661897d28+com.bumptech.glide.signature.EmptySignature#1341382+[1224x1020]+''+'ImageVideoBitmapDecoder.com.bumptech.glide.load.resource.bitmap'+''+'BitmapEncoder.com.bumptech.glide.load.resource.bitmap'+'GifBitmapWrapperDrawableTranscoder.com.bumptech.glide.load.resource.transcode'+''}
If I don't want to assume the size ahead of time, how can I cache it at all?
No, you can't cache images in memory unless they're the same size, so you'll need to know size ahead of time. It also needs to be the same signature, transformation and any added options. If any of these are different, your EngineKey hashCode will be different and it'll be a cache miss.
Note I'm assuming you're talking about memory caching as that's what preload is for and that's what the logs in Engine are talking about. You'll see Started new load in Engine for a memory cache miss and Loaded resource from cache for a memory cache hit.
If it's disk caching you're looking for, it's possible it's working as you intended. You need to enable the other logging to check this, so run adb shell setprop log.tag.Glide VERBOSE and look for either Finished loading BitmapDrawable from DATA_DISK_CACHE or Finished loading BitmapDrawable from DATA_DISK_CACHE or Finished loading BitmapDrawable from RESOURCE_DISK_CACHE in your LogCat.
Related
I am using
glide.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.preload()
to preload images.
However, I need them to be in memory and not just on disk, so it's loaded in ImageView more quickly, the way it does when I revisit the images after loading them in ImageView once.
I have also tried
glide.load(url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(PreloadTarget.obtain(glide, PreloadTarget.SIZE_ORIGINAL, PreloadTarget.SIZE_ORIGINAL))
without much luck.
PS: I have visited this question and others, answers are outdated hence this question.
Referring to this article you can cache the image in the memory then use
onlyRetrieveFromCache( true )
to load the image only from memory
In order to get cached resource from the memory cache, loaded objects should be exactly equal. Read in docs here. To verify if your preloaded object and object loaded to ImageView are the same enable Glide logs for the Engine class.
adb shell setprop log.tag.Engine VERBOSE
Then compare the EngineKey objects that you see in logs for preload and for actual load to ImageView. They should not only have the same url and signature, but also transformations and options.
In case you load into ImageView, to not add any transformation based on ImageView params, use the
RequestOptions().dontTransform()
for the load to ImageView request.
Preload with Glide v4.6.1
RequestOptions requestOptions = RequestOptions
.diskCacheStrategy(DiskCacheStrategy.ALL);
Glide.with(appContext)
.asBitmap()
.load(model)
.apply(requestOptions)
.submit();
Scenario:
I have a large GIF image which I want to cache the first time user opens the app using Glide - Image Loading and Caching library. After that whenever user opens the app, I want to show the cached version if present. This GIF URL will expire after a given interval. When it expires, I fetch the new GIF URL and display/cache that for future use.
What I tried:
I went through Caching and Cache Invalidation on Glide's github page. I also went though the Google Group thread Ensuring That Images Loaded Only Come From Disk Cache, which shows how to get the image form cache. I also went through How to invalidate Glide cache for some specific images question.
From the links above I see the following code sniplet which shows how to load the image from cache. However this only tries to get the image from cache. If its not present in cache, it doesn't try to get from the network and fails:
Glide.with(TheActivity.this)
.using(new StreamModelLoader<String>() {
#Override
public DataFetcher<InputStream> getResourceFetcher(final String model, int i, int i1) {
return new DataFetcher<InputStream>() {
#Override
public InputStream loadData(Priority priority) throws Exception {
throw new IOException();
}
#Override
public void cleanup() {
}
#Override
public String getId() {
return model;
}
#Override
public void cancel() {
}
};
}
})
.load("http://sampleurl.com/sample.gif")
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(theImageView);
Questions:
Is there a cleaner way to achieve the following: Show the GIF image from the cache if present else download the GIF, cache it for later use and show it in the ImageView.
The caching article above mentions the following:
In practice, the best way to invalidate a cache file is to change
your identifier when the content changes (url, uri, file path etc)
The server sends a different URL to the app when the previous one expires. In this case, I believe the old image will eventually be Garbage Collected? Is there a way to force remove the image from the cache?
On a similar note, is there a way to prevent the Garbage Collection of an image with specific key (to prevent downloading the large file again) and then later instruct to delete the old image from cache when the URL changes?
You don't need a custom ModelLoader to show the GIF from cache if present and fetch it otherwise, that's actually Glide's default behavior. Just using a standard load line should work fine:
Glide.with(TheActivity.this)
.load("http://sampleurl.com/sample.gif")
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(theImageView);
Your code will prevent Glide from downloading the GIF and will only show the GIF if it is already cached, which it sounds like you don't want.
Yes, the old image will eventually be removed. By default Glide uses an LRU cache, so when the cache is full, the least recently used image will be removed. You can easily customize the size of the cache to help this along if you want. See the Configuration wiki page for how to change the cache size.
Unfortunately there isn't any way to influence the contents of the cache directly. You cannot either remove an item explicitly, or force one to be kept. In practice with an appropriate disk cache size you usually don't need to worry about doing either. If you display your image often enough, it won't be evicted. If you try to cache additional items and run out of space in the cache, older items will be evicted automatically to make space.
Glide.with(context)
.load("http://sampleurl.com/sample.gif")
.skipMemoryCache(true)
.into(imageView);
You already noticed that we called .skipMemoryCache(true) to specifically tell Glide to skip the memory cache. This means that Glide will not put the image in the memory cache. It's important to understand, that this only affects the memory cache! Glide will still utilize the disk cache to avoid another network request for the next request to the same image URL.for more read this
Glide Cache & request optimization.
Happy coding!!
Its been sometime I started using Picasso for Image Loading in Android. The usual scenario is , it downloads images and cache it and if later needed it retrieves from Cache.
just found this use case,
if the ImageURL ends with .(jpg,png, etc etc .....)
Ex:http://www.androidguys.com/wp-content/uploads/2014/07/android-for-wallpaper-8.png
Picasso work as expected ,
but if the imageURL's are of type
http://cloud.clubsalive.com.au/download/33/404e58cf-d890-4eaa-981e-c2f3442f9348
then its not reloading from cache , its downloading every time when the view is loaded.
Is it a normal behavior of Picasso ???
Your image is giant. Try to increase cache size. Or scale down your image
I am trying to use a disk cache (not a memory cache) so i download my images from an urls and put it in a grid view. I want to download my images only one time.
I found this example (bitmapFun) in google site: http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
I found this example a bit complicated.
There are many objects in util package (AsyncTask, DiskLruCache, ImageCache, ImageFetcher, ImageResizer, ImageWorker, Utils)
Is there a way or a tutorial that show how can i use a disk Lru cache without using all those object.
I don't want to resize my image and i was not able to remove ImageResizer class.
Here you have good answer :Android image caching. Quotation :
"Consider using Universal Image Loader library by Sergey Tarasevich. It comes with:
//Multithread image loading. It lets you can define the thread pool size
//Image caching in memory, on device's file sytem and SD card.
//Possibility to listen to loading progress and loading events
Universal Image Loader allows detailed cache management for downloaded images, with the following cache configurations:
UsingFreqLimitedMemoryCache: //The least frequently used bitmap is deleted when the cache size limit is exceeded.
LRULimitedMemoryCache: //The least recently used bitmap is deleted when the cache size limit is exceeded.
FIFOLimitedMemoryCache: //The FIFO rule is used for deletion when the cache size limit is exceeded.
LargestLimitedMemoryCache: //The largest bitmap is deleted when the cache size limit is exceeded.
LimitedAgeMemoryCache: //The Cached object is deleted when its age exceeds defined value.
WeakMemoryCache: //A memory cache with only weak references to bitmaps.
A simple usage example:
ImageView imageView = groupView.findViewById(R.id.imageView);
String imageUrl = "http://domain.com/image.png";
ImageLoader imageLoader = ImageLoader.getInstance();
imageLoader.init(ImageLoaderConfiguration.createDefault(context));
imageLoader.displayImage(imageUrl, imageView);
This example uses the default UsingFreqLimitedMemoryCache.
I have trouble when I'm using Glide in my app. As I've understood, if image was downloaded once and I request image from cache from other activity, Glide must show image quick. And I got this behavior, but not in my app. Image loads very slow (about 3 seconds), although in another app it was about 0.4 second.
My code with calling Glide:
Glide.with(this)
.load(url)
.signature(new StringSignature(url))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(mHeader);
And in other activity code are same.
May you help me?
Thanks
You don't need the signature(url) part, the model (url String in your case) is already a part of the cache key.
The problem may be that your header changes size. The view size (= resulting Bitmap size) needs to be constant for a cache hit. However since you're doing ALL caching the load should still be fast. Is there anything changing in the url maybe, like a sessionid or similar? That would make the cache miss.
If the url you're loading is an animated GIF RESULT caching can be the culprit, here's a reference.