Closed adrielcafe closed 2 years ago
Hmm I'm not sure it makes sense to add this to Coil. Coil is intentionally built to only support Drawables
as the result of loading an image. Most load
operations don't have a file we can return (Uris, resources, bitmaps). Also, since Coil is backed by OkHttp
isn't not possible to get access to the underlying disk cache.
Hi @colinrtwhite I am also looking for something similar. My use case is if image gets deleted from server then I need to delete just that image from device local cache. But currently I can't find a way to just fetch that particular image from cache.
Is there a way we can check if an image is already cached or not? Does Coil supports deleting selected file from cache? If yes then how can I achieve it?
@DeepPSingh Coil relies on OkHttp for its disk cache. Unfortunately, the cache isn't set up for easy access, however you could probably access its files using Cache.urls()
and Cache.key()
. That'll let you iterate over the current files in the disk cache. You can get the default Coil Cache
instance using CoilUtils.createDefaultCache
.
Closing this since I don't think this is likely to be added for 1.0 as it would require reworking Target
s.
glide.downloadOnly().load(url)
.into(object : CustomTarget<File>() {
override fun onLoadCleared(placeholder: Drawable?) {}
override fun onResourceReady(
resource: File,
transition: Transition<in File>?) {
subsamplingScaleImageView.setImage(ImageSource.uri(resource.toUri()))
}
})
I need it too. SubsamplingScaleImageView can display large image without compression. Users can also save image from the cache to avoid downloading again
+1 for this. Any chances this can be re-opened? Displaying large images through coil is a bit of a pain right now because libraries like SubsamplingScaleImageView
only take in files instead of Drawables.
I tried accessing OkHttp's cache directly, but the code is very fragile:
val coilCache = CoilUtils.createDefaultCache(context)
val file = File(coilCache.directory, "${Cache.key(imageUrl.toHttpUrl())}.1")
Sounds good, reopening this for discussion. Now that Coil is a little more settled this is something I'd like to add to Coil, however adding it has the following challenges:
Call.Factory
instead of an OkHttpClient
. This has some nice properties since it allows delaying the OkHttpClient
init to a background thread or using a custom network library that can be adapted to implement Call.Factory
.OkHttp
's Cache
. There are no public methods on Cache
to keep it from being evicted.Ultimately I think we might need to add an ImageLoader.cache
method that gives Coil knowledge of the cache, however that solution isn't great since the cache passed to ImageLoader.cache
could be different from the actual cache used by the OkHttpClient
.
Maybe we could add CoilUtils.getCacheFile(cache: Cache, url: HttpUrl): File?
until we figure out a better solution?
Yep, I agree that coil will need to own its cache in order to control the lifecycle of cached images. Otherwise, I imagine the files can be evicted while they're shown on the UI.
Having a nifty function that retrieves cache files would be a good stop-gap in the meantime!
It's actually fine if image files are evicted while on screen (Glide and Picasso allow this too). Once they're decoded the file can be safely evicted. If I recall correctly Glide doesn't guarantee the lifetime of the File
it returns, however it does bump the returned File
to the top of the LRU cache. I think if we can bump the file then we'll probably be ok since we'll have parity with Glide.
Once they're decoded the file can be safely evicted
TIL.
I think if we can bump the file then we'll probably be ok since we'll have parity with Glide.
This sounds great!
+1 for this. Any chances this can be re-opened? Displaying large images through coil is a bit of a pain right now because libraries like
SubsamplingScaleImageView
only take in files instead of Drawables.I tried accessing OkHttp's cache directly, but the code is very fragile:
val coilCache = CoilUtils.createDefaultCache(context) val file = File(coilCache.directory, "${Cache.key(imageUrl.toHttpUrl())}.1")
I came here looking for way to use Coil with SubsamplingScaleImageView, and your solution is working for me :)
As long as the disk cache is big enough to hold everything currently on screen, i think this will be okay.
I've just published 2.0.0-alpha01
which makes the disk cache public. It's experimental and subject to change, but you can get access to the image's file like so:
context.imageLoader.diskCache?.get(url)?.use { snapshot ->
val imageFile = snapshot.data.toFile()
// Read or copy the file. You **must** close the snapshot (`use` closes the snapshot)
// or it'll prevent writing to that entry until your app is killed.
}
The new disk cache also has support for editing/removing entries. Check it out!
Looks good, thanks @colinrtwhite!
Closing this out as the new disk cache is available in a stable release (though marked with @ExperimentalCoilApi
) in 2.0.0
.
@colinrtwhite Hello. The project we are working on with the team I am part of has a complicated functionality with big image gallery, positioned in different Channels, which can have subchannels, the Subchannels can have their own Subchannels, etc.(F.E. You have a Picture of World Oceans, you click on it and receive big amount of Ocean pictures from different places in the World, you choose one of them and you receive more detailed collection of pictures for the given place). We would like to be able to download and store the images in Cache for Subchannels in Advance when the User opens the Parent channel and this to happen hidden from him. Glide does this by downloadOnly
Glide .with(context) .downloadOnly() .load(imageUrl) .submit() .get()
The whole point is better UX - the images not to start appearing when the user opens the page of the Gallery, rather they to already be there because they are already stored in the cache. Can you add this for future versions?
Is your feature request related to a problem? Please describe. I'm looking for a way to get the image file from a preloaded image, but seems Coil lacks this feature at the moment.
Describe the solution you'd like On Glide I do:
Would be nice if we have at least one of these options in Coil: