-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixed Android's StreamImageSourceService.LoadDrawableAsync() #14109
Conversation
@jonathanpeppers @mattleibow I seem to recall some issues with using post on the android side previously, does that sound familiar at all? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the main thing missing here is some kind of test.
Can we add a test to this file?
protected void onResourceCleared(@Nullable Drawable placeholder) { | ||
this.view.setImageDrawable(placeholder); | ||
post(() -> this.view.setImageDrawable(placeholder)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found the docs on this callback:
It doesn't say what thread this is on, but it must be the main thread because view.setImageDrawable
would throw?
Reviewing some examples on GitHub:
- https://github.com/CzBiX/v2ex-android/blob/f6a79a91b84ae8030930231d965845798c4ce0a8/app/src/main/java/com/czbix/v2ex/parser/AsyncImageGetter.java#L196-L198
- https://github.com/signalapp/Signal-Android/blob/2cef06cd6ef2ed70fdab3fcb525df9909f18aa5a/app/src/main/java/org/thoughtcrime/securesms/util/AvatarUtil.java#L71-L74
I don't think we need this post()
, did it fix something when you added it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It did not fix anything specific, no. I think that, technically, only the ConfigureAwait(false) removal is needed. The post() calls were suggested changes that might help make MAUI more robust against this type of problem if customers did things on other threads.
post(() -> { | ||
// set the image | ||
this.view.setImageDrawable(resource); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change to post()
might be OK, did this fix something?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removing the ConfigureAwait(false) from StreamImageSourceService.Android.cs seemed to have worked by itself. The post() changes didn't fix anything on their own (i.e. I tested adding back the ConfigureAwait(false) and ended up with errors again).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we don't need this anymore then? Is there any fears that there are related issues?
I'll work on adding a test today |
@jstedfast this looks potentially related: #14128 Could you maybe validate your changes against that repro too? |
@Redth yea, that definitely looks related. I'll test it to verify. |
d26c380
to
b526ccb
Compare
I've been unable to get the DeviceTests to build or run. Would anyone else be willing to write the test(s) for this? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come the tests are not catching this? Are we missing something in the core device tests that we should be adding this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How come the tests are not catching this? Are we missing something in the core device tests that we should be adding this?
91d41c3
to
59cfd4c
Compare
Any chance we can get this merged? |
Can we add a test? #14109 (review) |
@jonathanpeppers How would you write a test for this? |
We should be able to add a test here that loads an image from an Previously, any |
Does the test fail without your changes? Was the issue also related to setting the property from a background thread, or if the stream went to the background thread? Maybe the task should be I do know we have images in our sample that I am sure load, but we do basic things. |
@mattleibow The customer sample did not set the stream in a background thread - they set it in the main thread. |
Argh, not sure why it's getting a null stream for the embedded image when run on the bots but not locally. Doesn't seem to make sense :( |
Still getting failures. It looks like the failures are only on iOS. Is there something specifically different about iOS that embedded resources would be named differently or somehow not embedded, perhaps? |
@mattleibow do you know?
The stream isn't |
src/Core/src/ImageSources/StreamImageSourceService/StreamImageSourceService.Android.cs
Show resolved
Hide resolved
Transition back to the calling thread context (which should theoretically be the main thread). Fixes issue #14052
3046dc3
to
83580c6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, assuming the new test verifies the fix.
src/Core/src/ImageSources/StreamImageSourceService/StreamImageSourceService.Android.cs
Show resolved
Hide resolved
When is this fix released in a non-preview MAUI version? |
If we backport this, we should regenerate the android file |
/backport to net7.0 |
Started backporting to net7.0: https://github.com/dotnet/maui/actions/runs/5811072947 |
Description of Change
The original issue is that images were being loaded/set on the Image control in a non-UI thread causing an unhandled exception stating, "Only the original thread that created a view hierarchy can touch its view".
Android's StreamImageSourceService.LoadDrawableAsync() incorrectly had a ConfigureAwait(false) on an awaited call to get the image data stream which meant that the subsequent LoadImageFromStream() call would not happen on the original thread.
As added precaution, modified MauiCustomViewTarget.java to post view.setImageDrawable() calls to the main (UI) thread as well.
Issues Fixed
Fixes #14052
Fixes #15397