I have recyclerview in my MainActivity and it is filled with images. I'm using this code to polulate them:
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.dontTransform()
.into(view)
when user clicks on the image i'm starting new activity and show the same image (and also measuring time). this code is from onCreate method:
val t1 = System.nanoTime()
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.dontTransform()
.listener(object : RequestListener<String, GlideDrawable> {
override fun onResourceReady(resource: GlideDrawable?, model: String?, target: Target<GlideDrawable>?, isFromMemoryCache: Boolean, isFirstResource: Boolean): Boolean {
val t2 = System.nanoTime()
log("load time: ${(t2 - t1) / 1e9}")
return false
}
override fun onException(e: Exception?, model: String?, target: Target<GlideDrawable>?, isFirstResource: Boolean): Boolean {
return false
}
})
.into(view)
it takes about 100 - 120 ms to load:
07-16 17:56:08.175 E/﹕ load time: 0.123018802
07-16 17:56:10.762 E/﹕ load time: 0.099200312
07-16 17:56:12.929 E/﹕ load time: 0.104578125
this is too slow for me, so I tried to call preload() first, wait for it to finish and then start new activity:
val t1 = System.nanoTime()
Glide.with(this)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.dontTransform()
.listener(object : RequestListener<String, GlideDrawable> {
override fun onResourceReady(resource: GlideDrawable?, model: String?, target: Target<GlideDrawable>?, isFromMemoryCache: Boolean, isFirstResource: Boolean): Boolean {
val t2 = System.nanoTime()
log("preload time: ${(t2 - t1) / 1e9}")
startNextActivity(url)
return false
}
override fun onException(e: Exception?, model: String?, target: Target<GlideDrawable>?, isFirstResource: Boolean): Boolean {
return false
}
})
.preload()
result was strange:
07-16 18:20:47.948 E/﹕ preload time: 0.040331459
07-16 18:20:48.094 E/﹕ load time: 0.0976725
07-16 18:20:51.515 E/﹕ preload time: 0.023336198
07-16 18:20:51.671 E/﹕ load time: 0.127479374
07-16 18:20:57.752 E/﹕ preload time: 0.033461511
07-16 18:20:57.904 E/﹕ load time: 0.103768177
preload is super fast, but load time has not changed at all.
so what is the point of having preload if it doesn't do anything?
This is because your cache keys doesn't match and that could be because
you're views have different size in the first and second activity. Use
Override(size, size) and check the results, plus if you want to share the
image in different activity it's better to use application context.
You don't need to call prelaod if you load the exact same image (same size, same transformations,...), preload is to put the image in the cache which your first activity's load call will do that by default.
1) cache keys are matching perfectly, .diskCacheStrategy(DiskCacheStrategy.SOURCE) and .dontTransform() ensure that. also it works (the same) without network.
2) Are you trying to say that different contexts have different memory caches?
I think your target sizes are different in your second call compared to your first call.
ok, I tried
.diskCacheStrategy(DiskCacheStrategy.SOURCE)
.override(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL)
.dontTransform()
and now it is fast.
so it was missing the memory cache and not missing the disk cache?
I thought .dontTransform() implies that I need full size image anyway.
I'm sorry for being rude. Thank you very much for your help!
you're welcome :)
What is that language you use, where you can override fun to be more fun? :)
dontTransform only disables the auto-transformation (fitCenter/centerCrop) based on ImageView.scaleType or any other set transform().
I think the target size is still given to Downsampler which tries to load the smallest possible Bitmap without quality loss (Glide philosophy). Preload uses original size, but into(ImageView) still reads the laid out size. This was the memory cache miss avoided with override(width, height).
I suggest that if you use a fixed size (dp in xml) ImageView in the activity or you can predict the size accurately (like screen size) you preload(width, height) to use less memory. This will need RESULT or BOTH cache though, trading disk space for memory usage, also meaning faster second loads from disk cache (less pixels and no downsampling).
I have custom ImageView that displays only specified part of the image. So my image should be larger than ImageView. I think i need to implement custom tranformation at some point.
fun language is Kotlin. it has some cool features like extension methods, lambdas that work even on java 6, null safety, etc. and its stable enough for my little project.
I had this same problem. After a bit of debugging & snooping around the cache directory, I noticed that the images cached during preload were identical to those cached afterward. The only difference was the file name, which is derived from the key.
So I put a breakpoint inside of Engine.load so that I could inspect the key at runtime. I found that the keys were almost identical except the ImageView one had FitCenter.com.bumptech.glide.load.resource.bitmap but my prelaod key did not (even though I wasn't calling .fitCenter() anywhere!) Adding .fitCenter() to just the preload call fixed the problem. Alternatively, adding .dontTransform() to both calls also did the trick.
If anyone else lands here with this problem, I'd suggest inspecting the key (effectively decoding the cache file names) so that you can pinpoint the difference that's causing a cache miss.
Most helpful comment
I had this same problem. After a bit of debugging & snooping around the cache directory, I noticed that the images cached during preload were identical to those cached afterward. The only difference was the file name, which is derived from the key.
So I put a breakpoint inside of Engine.load so that I could inspect the key at runtime. I found that the keys were almost identical except the ImageView one had
FitCenter.com.bumptech.glide.load.resource.bitmapbut my prelaod key did not (even though I wasn't calling.fitCenter()anywhere!) Adding.fitCenter()to just the preload call fixed the problem. Alternatively, adding.dontTransform()to both calls also did the trick.If anyone else lands here with this problem, I'd suggest inspecting the key (effectively decoding the cache file names) so that you can pinpoint the difference that's causing a cache miss.