I am new in glide and want to migrate my app from universalimageloader to glide.
I want to convert cached image from the disk into image file, and show it into an ImageView.
When I use universalimageloader, I can do it easily with this way:
File imageFile = DiskCacheUtils.findInCache(image_url, ImageLoader.getInstance().getDiscCache());
//then show it into image view
String file_target = "file://"+imageFile.getPath();
ImageLoader.getInstance().displayImage(target, imageView);
However I have not found a way from documentation to do that in Glide.
Is it possible?
Hi, welcome to Glide!
Glide doesn't support directly accessing the cache by design. Cache is a transparent storage, meaning you don't need to know about it. Also in Glide the caching is much more fine grained than just the url as key, see EngineKey.
So the solution is to load normally and it will be loaded from the cache if it's there, otherwise downloaded and then loaded. Look into .diskCacheStrategy() for more control as to what gets cached.
Is this offline mode? If so check out the comments in Ensuring That Images Loaded Only Come From Disk Cache on 12 June 2015
For other use cases see the network of related issues starting with #459 OR describe your use case here in more detail so we can suggest solutions specific to you.
hm, I'm sorry, I am confused with the discussion on the link above (#459), it did not seem suitable with my case.
My case is convert cached image into jpg file. First, load image onto an ImageView when networks connected, and cache it into disk with .diskCacheStrategy(). I perform it without download image separatedly, but just show it like this:
Glide.with(context)
.load(image_url)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(imageView);
Then, I want to use the cached image stored in the disk to send to my server without having to download it again or download it separately. In other case, when network is disconnected I want to save it as wallpaper from my app.
If you use DiskCacheStrategy.SOURCE (included in ALL) your _original_ image will be stored in the phone and likely available when you need it offline. Cache will be always consulted first before going for the network.
Notice that the ShareTask should use the same url (=model), and even if it says downloadOnly it _will_ read the cache (if present).
Also notice how you receive a File object in onPostExecute, you can open it with a stream and pass it to WallpaperManager.
If you want the full sized image use downloadOnly(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).
@sjudd the DownloadOptions.downloadOnly doc doesn't mention SIZE_ORIGINAL, but that's the users only interface with this feature. Only into() and preload() docs mention it.
_Hope the above clears it up, but feel free to ask more._
@sjudd Are you considering adding an API like DiskCacheUtils.findInCache? If not I think this can be closed as workarounds exists for most cases (#459, #639, #90).
will there be a method such as DiskCacheUtils.findInCache(url) in the future? or does something like that already exist.
So far as I remember all of the queries that led here were X-Y problems: someone wanted to check if a file exists in cache to do something that's already possible via another way in Glide, or doesn't make sense, or wanted to hack the cache by removing files, which is weird considering removal is automatic.
I think adding a method would just encourage blocking I/O on the UI thread, which is a bad thing to do. Feel free to open a new issue and we can see if your use case could prove this method viable.
opened https://github.com/bumptech/glide/issues/810 and tried to explain my problem in simpler terms
@sjudd bump: https://github.com/bumptech/glide/issues/509#issuecomment-148857953
I think findInCache() is must for my case:
more explains:
if the image was cached, I can wait until it loaded from cache, and then show the animation, If not, I can't wait, the loading time is important for me, this is why I need to know if an image was cached.
@jeaking why don't you always animate to the thumbnail which you know is always available (from memory cache), because the user just tapped on it. I think it's safe to assume that the user will wait for a thumb to load before tapping, but if you can't make that assumption a combination of NetworkDisablingLoader, downloadOnly and listener should be enough to achieve what you want without doing any disk I/O on UI. If you get a file in listener then it is cached, otherwise you get a callback to onException.
In my code I have a reason that I must get image from server with id of image and the return is not direct link but a byte array. I see that Glide come with load(byte[]) method but I want to check if the image is loaded and cached so I wouldn't waste time on load byte array on server. How can I check if there are image In cache
private Bitmap loadBitmap(String id){
//download image to stream and decode image to byte array
byte[] byteArray = getByte(id);
if(byteArray != null){
Bitmap bitmap = Glide.with(context)
.load(byteArray)
.asBitmap()
.signature(new StringSignature(id))
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(CustomCardView.width, CustomCardView.height)
.get();
if(bitmap != null) return bitmap;
}
return null;
}
@kanoonsantikul You should be using a custom model and all caching would be done for you automatically in a cleaner way, just provide a fetcher that returns an InputStream (even if it's ByteArrayInputStream).
As far as I remember there's no point in caching a byte[] because you need the byte[] to hit the cache... catch 22 (see RequestManager.fromBytes). Feel free to open a new issue after you tried a custom model and you need more info.
Since you're doing a sync load with signature you could also try load((byte[])null) because if it's in cache, the signature will hit it anyway; and if not you'll just get a null or exception.
I try load((byte[])null) to check cache like you told but it appear to always throws exception even if image are cached
@kanoonsantikul Ah, sorry, the null check is earlier in the flow than I thought, try load(new byte[0] /*won't be used to decode, just satisfy signature*/); but remember that this is a hack of a hack, the better approach is to use a custom model where Glide properly can decide if it's in the cache or not.
Thank @TWiStErRob Can you tell me where I can read about custom model
@kanoonsantikul The key classes are: StreamModelLoader, ModelLoaderFactory; it needs to be glide.register'd in a GlideModule. You can find a lot of examples in this issue tracker, or in my support code. _Please open a new issue if you have more questions, let's not hijack this thread._
@TWiStErRob after using DiskCacheStrategy.ALL and replace source downloaded image, that load cached image? how can i refresh or new cached image ?
@tux-world I don't know how you did "replace source downloaded image", but you probably wrote directly into the disk cache, which is an unsupported hack. Use signature to evict an item from cache and force a new download.
I have a list view with small images and when clicked it opens a new activity showing the full image. How can I load the cached image in the thumbnail attribute while the full image is not loaded?
This is how I am doing in the list view:
Glide.with(context)
.load(url)
.placeholder(R.drawable.ic_product_placeholder)
.error(R.drawable.ic_product_no_image)
.animate(android.R.anim.fade_in)
.into(imageView);
And here is what I am trying to do in the new activity:
Glide.with(context)
.load(url)
.thumbnail(Glide.with(context)
.load(url)
.override(width, height))
.into(imageView);
Obs: Currently the URLs are the same for the small and large size. The width and height I am getting from the ImageView in the list view.
I set a listener on the thumbnail and _isFromMemoryCache_ is _false_ when I open an image for the first time.
@db-dblank that's pretty close the thing you're probably missing is the matching transformation. Notice that GenericRequestBuilder.into(ImageView) reads the scaleType, but thumbnail arguments need explicit transformations. So adding .fitCenter() after .override should be sufficient. See wiki for more on how to diagnose these kinds of issues (cache key matching) and see #1279, #1186 for similar issues. Also make sure you add .diskCacheStrategy(ALL) to your list load and thumbnail load, and .diskCacheStrategy(SOURCE) to your full image load to prevent re-downloading.
Thanks @TWiStErRob. Adding .fitCenter() did it.
@TWiStErRob Is NetworkDisablingLoader not available anymore?
@jotish it was never part of the library, just a class that was consistently referenced in GH issues, search the issues or Google for the class name.
Hi,
I see your reason why you don't support getting an image from the cache directly.
However I think my usecase would be quite feasible, maybe you could take stuff like that into consideration:
If i need to get an image remotely, I need to get a token from an android account and put it into an authorization header (this was implemented by implementing a ModelLoaderFactory and registering it in a OkHttpGlideModule which in turn is referenced in the manifest).
The app is quite image-loading heavy. If the image is already cached, I don't need to insert the token into the http header. Those would be quite a few valuable milliseconds I could spare. At least assuming the cache lookup would be faster than fetching the token from the account manager.
So a method only returning a boolean whether a certain image is already cached would be very helpful in this case.
Thanks,
@wurstnudl you can accomplish the same thing by only fetching your token in your ModelLoader's DataFetcher. The DataFetcher won't be called if the data isn't in the disk cache so if you wait to load the token until it is called, you'll avoid spending the extra time for images that are in the disk cache.
I also need some caching related information. I want to store the image into cache before getting it uploaded.
I am uploading Image from my android device before uploading of Image, I want to copy that image to the GlideCache directory so that when the upload was done and if I put the code to display image, it should display the image directly without loading URL and downloading it into the cache.
I know Glide use InternalDiskCache by default to store the image into cache. But I want to store image in cache from local location and then want to display that stored image based on URL.
Please let me know if you are not getting me properly.
Thanks.
Sincerely,
Shreyash
@TWiStErRob Need your help in above question.
@ShreyashPromact you're probably better off opening a new issue since it doesn't sound like your request is related to the primary one here.
We've gone about as far down this road as I think we're going to for the time being. It's plausible that a DiskCache API refactor will make this easier at some point in the future, but it wouldn't be an explicit goal.
You can use .onlyRetrieveFromCache(true) and asFile() to try to retrieve paths to most cached images on background threads.
Most helpful comment
Hi, welcome to Glide!
Glide doesn't support directly accessing the cache by design. Cache is a transparent storage, meaning you don't need to know about it. Also in Glide the caching is much more fine grained than just the url as key, see
EngineKey.So the solution is to load normally and it will be loaded from the cache if it's there, otherwise downloaded and then loaded. Look into
.diskCacheStrategy()for more control as to what gets cached.Is this offline mode? If so check out the comments in Ensuring That Images Loaded Only Come From Disk Cache on 12 June 2015
For other use cases see the network of related issues starting with #459 OR describe your use case here in more detail so we can suggest solutions specific to you.