maui: CollectionView is displaying incorrect images
Description
I’m creating an app, where I recieve a lot of images from MQTT (as byte[] (byte[] -> ImageSource)). I often clear everything and then get flooded by them over and over again. The problem I’m seeing for quite some time is this: the images are not consistant with the images that are actually being send to the app. It seems to be the caching strategy or caching still being saved in between the sessions. Most of the time it occurs and disappears as UI refreshes/updates (insert or deletion).
Steps to Reproduce
- Download the sample project TestImages.zip
- launch the sample project on android and scroll to the bottom (hope it wont crash)
- Open MainPage.xaml.cs and switch images in lines 23/24 from:
//Animals.Add(new Animal(base64CatImage, "cat" + a));
Animals.Add(new Animal(base64DogImage, "dog" + a));
to
Animals.Add(new Animal(base64CatImage, "cat" + a));
//Animals.Add(new Animal(base64DogImage, "dog" + a));
- Launch the app again and scroll down
Expected behavior: First time you only saw dog images and now see only cat images
Actual behavior: Instead of seeing just cat images now, you see a dog images mixed in from time to time
Version with bug
6.0.400 (current)
Last version that worked well
Unknown/Other
Affected platforms
Android
Affected platform versions
Android 11
Did you find any workaround?
Sometimes refreshing the UI works o fix the issue, but it’s just a very temporary problem and usually makes it fail in another place in the UI
Relevant log output
No response
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Comments: 15 (6 by maintainers)
When using ImageSource.FromStream(), MAUI isn’t providing any information to Glide that Glide can use to build a reasonable key for caching the object. Glide requires a key implementation in a loader, but ours just uses
new ObjectKey(inputStream), which means that we’re just keyed off of some generic values of a Stream object. There’s nothing unique about it, so collisions are pretty much guaranteed.So an application runs, loads an image from a Stream via Glide, and Glide caches the image to disk with a key based on the Stream object. The next time the application runs and requests for Glide to load an image from a Stream, if the key created from the new Stream collides with the previous one (which is pretty much guaranteed to happen), then Glide loads up the cached image from disk, rather than the image from the actual Stream.
The only solution to get the correct image without API changes is to disable caching entirely for the
FromStream()path; this will force Glide to actually load up what’s in the Stream.In the future, if we want to provide the option of caching images from Streams, we’ll need to add an overload to pass an optional cache key into
FromStream(), and let the user define the key; we’d pass that value along to new overloads ofPlatformInterop.loadImageFromStream().Yeah, I just managed to reproduce this without a CollectionView. Just two images in a StackLayout. I’ll dig into the Glide caching docs tomorrow and see if I can figure out what’s going on.