Android fresco how to get save cache callback? - android

I got a question about android fresco library. Do you guys know how to get callback when file is saved in cache? Generally, we could get file from cache:
ImageRequest imageRequest= ImageRequest.fromUri(url);
CacheKey cacheKey= DefaultCacheKeyFactory.getInstance().getEncodedCacheKey(imageRequest);
BinaryResource resource = ImagePipelineFactory.getInstance().getMainDiskStorageCache().getResource(cacheKey);
File file=((FileBinaryResource)resource).getFile();
However, if I put this in onCreate() function, it will crash since the file was not in the cache yet. Do you guys know how I got get a callback when the fresco finish saving it? Is it DataSubscriber? Could you guys provide an example? I read the documentation but I couldn't figure out.
Thanks.

I am part of the Fresco team and may be able to help. Please see our documentation on how to properly get the encoded image bytes. There is a code example of how to get an InputStream of the encoded image (which is what is being stored in cache). You can then use those bytes directly, or if you need a File in order to pass it somewhere else, you should create your own file and store the returned bytes in it. There is no other safe way to deal with cached images because you have no guarantees that Fresco will not evict (delete) the cached file at any time.

Related

Image Cache Signature in Glide with Metadata

Users can change a picture (replace it). Once the user changes their image, I want the new image to get cached in Glide and the old image to get thrown out of the cache.
I've read everything online but I'm still at a loss on how to implement a good solution to this.
I've tried skipping the local memory and disk caches like when setting the image:
GlideApp.with(fragment)
.load(url)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(view);
This solution is SLOW because it now calls the new image every single time - it never caches the new image.
Glide documentation says:
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://github.com/bumptech/glide/wiki/Caching-and-Cache-Invalidation
But that is not possible for me, so Glide documentation then says:
Since it’s often difficult or impossible to change identifiers, Glide
also offers the signature() API to mix in additional data that you
control into your cache key.
And it gives this example:
Glide.with(yourFragment)
.load(yourFileDataModel)
.signature(new ObjectKey(yourVersionMetadata))
.into(yourImageView);
But here comes the issue. What would be a good "yourVersionMetadata"? How do I create and maintain it? I've seen examples like so:
.signature(new ObjectKey(Long.toString(System.currentTimeMillis())))
This causes the disk cache key to change every time I load the image, so it is SLOW. I just need it to change when the user replaces the image. Not every time the image loads.
Someone wrote:
You can do something like generate a new UUID or increment an integer whenever the image changes. If you go that route, you'll have to keep track of the current signature for each image somewhere. - https://github.com/bumptech/glide/issues/2841
I don't understand how to do this.
I also tried the Async task for completely deleting cache. It works, but again it's super slow (and Glide doesn't recommend using this approach).
I don't know how I can just insert the current signature (which should be faster) rather than creating a new signature every time the image loads. Help? It seems to replace an image and recaching it shouldn't be so difficult!
I worked on this for days.
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, and I successfully implemented them too. But to me, they seemed just as slow as skipping cache entirely.
Two options
1) To generate a unique signature for a file you can calculate the MD5 signature for it. It will always be unique for a file until it is modified. See how to generate the MD5 signature here.
2) Another way to set a unique signature could be using the last modified time of the file. If you are sure that only your app will be modifying the image and nothing else then you can also rely on this. To get the last modified time use:
File file = new File("path/to/image");
String signature = Long.toString(file.lastModified());

Glide caching behaviour

I have simple caching problem:
I have old "name.jpg", then customer uploads new "name.jpg" and clients dont see any changes, for them its still cached old "name.jpg".
I know how to turn off caching, but its not good decision, so I try to find better.
So question is:
How does caching work if I add get parameter after question mark?
For example I have url
http://example.com/name.jpg?cache_time=111
And then I replace it to
http://example.com/name.jpg?cache_time=222
Will it download second name.jpg and replace existing or not? I know its work with css or js files in browser, but know nothing about glide behaviour.
Whatever parameters you pass in the url query will be sent to the server serving the image and only if that server handles that exact parameter (cache_time) can there be any difference in behavior.
The caching glide does however is not based on what you send to the server, but rather on the configuration you give to glide.
I suggest you look up how glide handles caching, and perhaps manually invalidate the cache for a specific image when you know it has changed.
This is a good place to start: Remove image from cache in Glide library. It also has examples how to use signature()that is mentioned in the comment above.

android delete some pictures from cache Picasso

I am using Picasso to save a collection of pictures for offline viewing. Later I need to remove some pictures manually from the cache. I can delete all files from folder, but I don't need this. I need to delete 2 or 3 files from the cache. invalidate doesn't work for me. Can anyone help me?
You can clear in-memory cache in Picasso only per image:
Picasso.with(context).invalidate(imagePath);
Removing all cache is somewhat tricky and described here.
File cache is delegated to HTTP Client, so it's not possible to clear it from Picasso. For more information refer this answer.

Encryption while disk caching

So what I to achieve is to apply encryption while caching images on disk.
I have decided to go with Universal Image Loader, I understand I will have to add an custom
disk caching implementation of my own but I don't know where to start with.
How can I achieve this, encryption while writing byte stream in file and decryption while getting the stream only from file.
Any kind of help would be deeply appreciated :)
Thanks for not replying :P
But I did eventually end up solving it. And here is what I did, maybe It will help anyone else.
All I had to was to create a custom disk cache and custom downloader.
In custom disk caching class, in the method where UIL write byte stream to file, I encrypted the byte stream.
and In custom downloader, I override the method where it take byte stream from file and decrypted it.

Image Cache in android

I need to download image url and store it in cache as bitmap.My qus is is there any config that i have to do inorder to store the image bitmaps in cache..? Is there any need to create any cache file?
You should try this librairy : https://github.com/square/pollexor
Well, you just can put it in the app's cache (context.getCacheDir()). What I'd recommend is to use wasp: a cool Android library to handle Bitmaps safely (safe == avoid OutOfMemory exceptions which are pretty common), based on a LRU cache.
It also allows you to download images in the background and get a callback once your image is downloaded... or automatically set the image to an ImageView once it gets downloaded. It is open-source, and is available for Maven users too.
Disclaimer: I'm one of the developers working on wasp library.
Depending on how many images you want to cache, you can probably get away with an in-memory cache using a LruCache. I'd cache the downloaded byte array, not the Bitmap, because Bitmaps are Big Things and decoding byte array -> Bitmap is pretty fast.

Categories

Resources