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();
I am developing A App which requires loading multiple images from their urls. I save all the images in firebase storage. I am currently using a compressor to reduce the size.
newImageFile=new File(uri1.getPath());
try {
compressedImageFile = new Compressor(ProductAdd.this)
.compressToBitmap(newImageFile);
} catch (IOException e) {
e.printStackTrace();
}
baos = new ByteArrayOutputStream();
compressedImageFile.compress(Bitmap.CompressFormat.JPEG, 100, baos);
thumbData1 = baos.toByteArray();
and I using Glide to load the image from the url
Glide.with(context).load(imgUrl).into(holder.cutImg);
I wanted to know if there is any way I could improve to load images much faster. Maybe store them in a specific format.
You can load a thumbnail of the original image into the ImageView before the original image loads.
Glide.with(fragment)
.load(url)
.thumbnail(0.05f)
.into(imageView);
This will load the 5% quality of the original image into the view and when the complete image loads it will be replaced.
And if you're having a separate URL for thumbnail then
Glide.with(fragment)
.load(url)
.thumbnail(
Glide.with(fragment)
.load(thumbnailUrl))
.into(imageView);
Now when image loads it will be immediately loaded into the view, here you can use the transition for a smooth effect.
Glide.with(fragment)
.load(url)
.thumbnail(0.05f)
.transition(DrawableTransitionOptions.withCrossFade())
.into(view);
You can checkout my project in which I'm also first compressing the Image and storing a thumnail image to Firebase Storage and then loading it.
You can also try different DiskCacheStrategies but I would suggest to go with the default one, it works just fine!
Here are various DiskCacheStrategies:
.diskCacheStrategy(DiskCacheStrategy.ALL)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.diskCacheStrategy(DiskCacheStrategy.DATA)
.diskCacheStrategy(DiskCacheStrategy.AUTOMATIC)
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
You can use the disc strategy which will be used to store the image on the disc. So it may take time for loading at first but later it does not take time at all.
For Glide 4.x
Glide
.with(context)
.load(imgUrl)
.diskCacheStrategy(DiskCacheStrategy.DATA)
.into(holder.cutImg);
For Glide 3.x
Glide
.with(context)
.load(imgUrl)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.into(holder.cutImg);
Please note: This will not refresh the image if you just update the image without updating URL. SO if you want to see the updated image you must update URL and Glide will automatically download an image for you.
if you are using firebase storage for host your images : Using FirebaseUI you can quickly and easily download, cache, and display images from Storage with Glide. source
Glide.with(context).load(model.imageUrl).thumbnail(0.05f).into(holder.imageView)
I have several RecyclerView's inside my app, and all of them have items which have an ImageView, which are further populated with Glide, like this:
Glide.with(context)
.load(imageUrl)
.asBitmap()
.error(R.drawable.placeholder_avatar)
.centerCrop()
.into(mAvatarImageView);
In my Preference screen, users can disable loading of all remote images to save bandwidth.
What's the best way to tell Glide not to load images, without using a classic if-else conditions inside all RecyclerView adapters, which violates the DRY principle?
I'm looking for a method like this:
.shouldLoad(UserSettings.getInstance().isImageLoadingEnabled());
Assuming you are using Glide v4, there is a request option specifically designed for this purpose: RequestOptions.onlyRetrieveFromCache(boolean flag). When enabled, only resources already present in memory or disk cache are loaded, effectively preventing loads from the network and saving bandwidth.
If you use Glide v4 Generated API, this option is directly available on the GlideRequest returned by GlideApp.with(context).asBitmap().
Otherwise, you have to create a RequestOptions with this flag enabled and apply it :
RequestOptions options = new RequestOptions().onlyRetrieveFromCache(true);
Glide.with(context).asBitmap()
.apply(options)
.error(R.drawable.placeholder_avatar)
.centerCrop()
.into(mAvatarImageView);
If you will decide to use Kotlin you can create needed extension function:
fun <T> RequestBuilder<T>.shouldLoad(neededToLoad : Boolean) : RequestBuilder<T> {
if(!neededToLoad) {
return this.load("") // If not needed to load - remove image source
}
return this // Continue without changes
}
Then you can use it, as you describe in question:
Glide.with(context)
.load(imageUrl)
.shouldLoad(false)
.into(imageView)
It's fair to say, that you can create only one Kotlin file with shouldLoad() function and use it in Java, but code becomes ugly:
shouldLoad(Glide.with(this)
.load(imageUrl), false)
.into(imageView);
OR
RequestBuilder<Drawable> requestBuilder = Glide.with(this)
.load(imageUrl);
requestBuilder = shouldLoad(requestBuilder, true);
requestBuilder.into(imageView);
I am using Glide in one of my projects to show image from file.
Below is my code how I am showing the image:
Glide.with(DemoActivity.this)
.load(Uri.parse("file://" + imagePath))
.into(mImage);
The image at this location(imagePath) keeps on changing. By default Glide cache the image it shows in the ImageView. Because of this, the Glide was showing the first image from cache for new images at that location.
If I change the image at location imagePath with some other image having same name then the Glide is showing the first image instead of new one.
Two queries are:
Is it possible to always the image from File and not cache? This way problem will be solved.
Is it possible to clear image from cache before getting newly replaced image? This will also solve the problem.
This is how I solved this problem.
Method 1: When the URL changes whenever image changes
Glide.with(DemoActivity.this)
.load(Uri.parse("file://" + imagePath))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(mImage);
diskCacheStrategy() can be used to handle the disk cache and you can skip the memory cache using skipMemoryCache() method.
Method 2: When URL doesn't change, however, image changes
If your URL remains constant then you need to use Signature for image cache.
Glide.with(yourFragment)
.load(yourFileDataModel)
.signature(new StringSignature(yourVersionMetadata))
.into(yourImageView);
Glide signature() offers you the capability to mix additional data with the cache key.
You can use MediaStoreSignature if you are fetching content from media store. MediaStoreSignature allows you to mix the date modified time, mime type, and orientation of a media store item into the cache key. These three attributes reliably catch edits and updates allowing you to cache media store thumbs.
You may StringSignature as well for content saved as Files to mix the file date modified time.
As explained in the section Caching and Cache Invalidation of the Glide wiki:
Because File names are hashed keys, there is no good way to simply
delete all of the cached files on disk that correspond to a particular
url or file path. The problem would be simpler if you were only ever
allowed to load or cache the original image, but since Glide also
caches thumbnails and provides various transformations, each of which
will result in a new File in the cache, tracking down and deleting
every cached version of an image is difficult.
In practice, the best way to invalidate a cache file is to change your >identifier when the content changes (url, uri, file path etc).
Since you can't change the file path, Glide offers the signature() API that allows you sets some additional data to be mixed in to the memory and disk cache keys allowing the caller more control over when cached data is invalidated.
If you want to reload every time the image from the disk, you can change your code like this:
Glide.with(DemoActivity.this)
.load(Uri.parse("file://" + imagePath))
.signature(new StringSignature(String.valueOf(System.currentTimeMillis())))
.into(mImage);
There are two ways to handle Glide cache refresh,
Firstway: - Add below with glide implementation
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
Second way:
If you able to identify image changes then give your new file name in below,
.signature(new StringSignature(String.valueOf(fileName)))
or you want to load every time with latest images , use below
.signature(new StringSignature(String.valueOf(System.currentTimeMillis())))
Hope this helps.
This will remove cache memory which is stored by Glide.And it should be done in background otherwise it will throw exception
new Thread(new Runnable() {
#Override
public void run() {
Glide.get(MainActivity.this).clearDiskCache();
}
}).start();
Had troubles with Glide 4.2.0, StringSignature was not resolved.
Looks like StringSignature is not available anymore and you have to use ObjectKey instead.
So code looks like
Glide.with(imageView).
load(pathToImage).
apply(new RequestOptions().signature(new ObjectKey("signature string"))).
into(imageView);
If you save images to the same known filename as a convention and want to invalidate the Glide cache only when the file has changed, using the file modification timestamp can work well.
I was using such a convention for avatar images which I was downloading to File objects outside Glide, and then using Glide just to efficiently resize and make them round, etc.
So I ended up using the StringSignature strategy with the value of the file's lastChanged timestamp as the signature. Here's what the fluent code for that looks like:
Glide.with(this)
.load(avatarFile)
.diskCacheStrategy(DiskCacheStrategy.RESULT)
.signature(new StringSignature(String.valueOf(avatarFile.lastModified())))
.into(ivProfile);
}
where avatarFile is my java.io.File object, of course.
I had troubles with setting signature using Glide version 4.* with Kotlin.
After some time I ended up with this:
fun ImageView.loadUrl(url: String) {
var requestOptions = RequestOptions()
requestOptions.signature(ObjectKey(System.currentTimeMillis()))
Glide.with(this).load(url).apply(requestOptions).into(this)
}
It's an extension function for ImageView, and it's used this way:
imageView.loadUrl(url)
I Hope it will help someone
For Glide 4.3.+ library you need to something like this to ,
Glide.with(context)
.load(image_path)
.apply(new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true))
.into(imge_view);
In the latest versions we should use RequestOptions
RequestOptions Provides type independent options to customize loads with Glide in the latest versions of Glide.
Make a RequestOptions Object and use it when we are loading the image.
RequestOptions requestOptions = new RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE) // because file name is always same
.skipMemoryCache(true);
Glide.with(this)
.load(photoUrl)
.apply(requestOptions)
.into(profile_image);
I was using Glide to load a File, and here's what I ended up doing to make sure Glide's disk cache was invalidated every time my file changed (even though it had the same path):
Glide.with(context)
.load(bitmapFile)
.signature(new ObjectKey(bitmapFile.lastModified()))
.into(imageView);
I worked on this for days, and all the above-mentioned solutions are just slow as a sloth.
I know you've probably read this before and ignored it because you thought it would probably take a lot of work to change your code. But seriously, it's well worth it. The performance, as far as I can tell, beats all the other methods presented, it's Glide's recommended solution, AND you don't need to skip cache or create signatures so it keeps your code cleaner too.
FROM Glide:
In practice, the best way to invalidate a cache file is to change your
identifier when the content changes (url, uri, file path etc) when
possible. - https://bumptech.github.io/glide/doc/caching.html
SOLUTION:
Change the name of the image when the user uploads a new image. Get the file name and use that for example. Once the image URL has changed, Glide understands you have changed the image and will update the Cache accordingly. This has by far given me the best performance.
WHEN USING:
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
It never caches the images and this really makes images load slowly. You'd think Signatures are better for performance, but to me they seemed just as slow.
signature with GlideApp
GlideApp.with(imageView)
.load(url)
.signature(new ObjectKey(System.currentTimeMillis()))
.placeholder(R.drawable.sky)
.error(R.drawable.sky)
.into(imageView);
And finally Kotlin implementation (For Fragments):
Glide.with(activity)
.load(url)
.apply(RequestOptions()
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true))
.into(myImageView)
This worked for me
//use diskCacheStrategy(DiskCacheStrategy.NONE) after skipMemoryCache(true)
Glide.with(this)
.load(image)
.skipMemoryCache(true)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.into(imageview);
Programmatically simply you can use:
// must run on main thread
Glide.get(getApplicationContext()).clearMemory();
// must run in background thread
Glide.get(getApplicationContext()).clearDiskCache();
For More
This one worked for me!
Glide.with(DemoActivity.this)
.load(Uri.parse("file://" + imagePath))
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(mImage);
To benefit from the cache provided by Glide and ensure that the correct image is shown everytime, you can use the signature() API.
All you have to do is to set as signature an information that relates to the image file. When you replace that file, the information changes too and Glide knows it must reload it, ignoring the cache.
A valid information could be a digest (for example SHA-1) calculated on the file contents.
Glide.with(context)
.load(inputFile)
.signature(new StringSignature(sha1(inputFile)))
.into(targetImageView);
Here I found the following implementation of sha1() function:
public static String sha1(final File file) throws NoSuchAlgorithmException, IOException {
final MessageDigest messageDigest = MessageDigest.getInstance("SHA1");
try (InputStream is = new BufferedInputStream(new FileInputStream(file)) {
final byte[] buffer = new byte[1024];
for (int read = 0; (read = is.read(buffer)) != -1;) {
messageDigest.update(buffer, 0, read);
}
}
// Convert the byte to hex format
try (Formatter formatter = new Formatter()) {
for (final byte b : messageDigest.digest()) {
formatter.format("%02x", b);
}
return formatter.toString();
}
}
1) First clear disk cache.
private class ClearGlideCacheAsyncTask extends AsyncTask<Void, Void, Boolean>{
private boolean result;
#Override
protected Boolean doInBackground(Void... params) {
try {
Glide.get(getContext()).clearDiskCache();
result = true;
}
catch (Exception e){
}
return result;
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if(result)
Toast.makeText(getActivity(), "cache deleted", Toast.LENGTH_SHORT).show();
}
}
You can call from your ui with new ClearGlideCacheAsyncTask ().execute();
2) Clear memory cache
// This method must be called on the main thread.
Glide.get(context).clearMemory();
Source : https://bumptech.github.io/glide/doc/caching.html
you can use a time stamp, that time could be the file's date modified or System.currentTimeMillis()
this works perfectly
Glide.with(DemoActivity.this)
.load(Uri.parse("file://" + imagePath+"?time="+System.currentTimeMillis()))
.into(mImage);
I want to use picasso to load an image from a url into a placeholder, but not store that image in cache - in other words, I want the image to be downloaded from the net directly to disk and then loaded from disk when needed. I understand there's a class called RequestCreator where you can specify memory policy - does anyone have an example of using picasso/requestcreator to do something like this?
So.. something like:
RequestCreator requestCreator = new RequestCreator();
requestCreator.memoryPolicy(MemoryPolicy.NO_CACHE);
....
merged with:
Picasso.with(context).load(someurl).fit().placeholder(someplaceholder).into(sometarget)..
Picasso supports this by it's skipMemoryCache() in the Picasso builder. An example is shown below.
Picasso.with(context).load(imageUrl)
.error(R.drawable.error)
.placeholder(R.drawable.placeholder)
.skipMemoryCache()
.into(imageView);
With the new API you should use it like this so that it skips looking for it and storing it in the cache:
Picasso.with(context).load(imageUrl)
.error(R.drawable.error)
.placeholder(R.drawable.placeholder)
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.into(imageView);
NO_CACHE
Skips memory cache lookup when processing a request.
NO_STORE
Skips storing the final result into memory cache. Useful for one-off requests to avoid evicting other bitmaps from the cache.
For picasso:2.71828 or above version use the following for skipping using disk cache networkPolicy(NetworkPolicy.NO_CACHE) :
Picasso.get()
.load(camera_url)
.placeholder(R.drawable.loader2)
.networkPolicy(NetworkPolicy.NO_CACHE, NetworkPolicy.NO_STORE)
.into(img_cam_view);
Picasso 2.5.0
If you are using Picasso to load image from Internet, you have to use NetworkPolicy attribute.
.networkPolicy(NetworkPolicy.NO_STORE)
but live memory cache (Not disk cache) is useful, you might want to keep it.
just append this at the end of url.
"?=" + System.currentTimeMillis();