summaryrefslogtreecommitdiff
path: root/Xamarin.Forms.Platform.WinRT
diff options
context:
space:
mode:
authorE.Z. Hart <hartez@users.noreply.github.com>2017-04-25 12:16:25 -0600
committerRui Marinho <me@ruimarinho.net>2017-04-25 19:16:25 +0100
commitcdc405512844671bc3b2c8bd28f583036e5530a2 (patch)
tree881d68b4a26eecbbc77e76b86b3f322cd41b3e3d /Xamarin.Forms.Platform.WinRT
parent9631ec2d8bbac8b837955af238f322c1023af097 (diff)
downloadxamarin-forms-cdc405512844671bc3b2c8bd28f583036e5530a2.tar.gz
xamarin-forms-cdc405512844671bc3b2c8bd28f583036e5530a2.tar.bz2
xamarin-forms-cdc405512844671bc3b2c8bd28f583036e5530a2.zip
Better error handling for image loading errors on iOS/Android (#849)
* First run at removing async void image update methods Consistent error logging and IsLoading on Android,iOS,UWP Move error logging into image handlers for better messages Add demo of custom ImageRenderer error handling Update docs Make the test smaller so the results don't get pushed offscreen Fix namespace error * Update error handling for fast image renderer * Update 37625 test to use image we control * Add java disposed check to avoid ObjectDisposedException in async operations * Add disposed checks to legacy renderer; null check element before SetIsLoading * Check disposed on GetDesiredSize for fast renderer Use local disposed member where possible for disposed check * Check for disposal after async handlers in iOS * Add disposal checks after async methods in Windows * Reset linker settings on project; reduce redundant casts in ImageViewExtensions
Diffstat (limited to 'Xamarin.Forms.Platform.WinRT')
-rw-r--r--Xamarin.Forms.Platform.WinRT/ImageRenderer.cs63
1 files changed, 50 insertions, 13 deletions
diff --git a/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs b/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs
index 8798b20e..56026d18 100644
--- a/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs
+++ b/Xamarin.Forms.Platform.WinRT/ImageRenderer.cs
@@ -17,6 +17,7 @@ namespace Xamarin.Forms.Platform.WinRT
public class ImageRenderer : ViewRenderer<Image, Windows.UI.Xaml.Controls.Image>
{
bool _measured;
+ bool _disposed;
public override SizeRequest GetDesiredSize(double widthConstraint, double heightConstraint)
{
@@ -32,10 +33,20 @@ namespace Xamarin.Forms.Platform.WinRT
protected override void Dispose(bool disposing)
{
- if (Control != null)
+ if (_disposed)
{
- Control.ImageOpened -= OnImageOpened;
- Control.ImageFailed -= OnImageFailed;
+ return;
+ }
+
+ _disposed = true;
+
+ if (disposing)
+ {
+ if (Control != null)
+ {
+ Control.ImageOpened -= OnImageOpened;
+ Control.ImageFailed -= OnImageFailed;
+ }
}
base.Dispose(disposing);
@@ -55,7 +66,7 @@ namespace Xamarin.Forms.Platform.WinRT
SetNativeControl(image);
}
- await UpdateSource();
+ await TryUpdateSource();
UpdateAspect();
}
}
@@ -65,7 +76,7 @@ namespace Xamarin.Forms.Platform.WinRT
base.OnElementPropertyChanged(sender, e);
if (e.PropertyName == Image.SourceProperty.PropertyName)
- await UpdateSource();
+ await TryUpdateSource();
else if (e.PropertyName == Image.AspectProperty.PropertyName)
UpdateAspect();
}
@@ -94,7 +105,7 @@ namespace Xamarin.Forms.Platform.WinRT
Element?.SetIsLoading(false);
}
- void OnImageFailed(object sender, ExceptionRoutedEventArgs exceptionRoutedEventArgs)
+ protected virtual void OnImageFailed(object sender, ExceptionRoutedEventArgs exceptionRoutedEventArgs)
{
Log.Warning("Image Loading", $"Image failed to load: {exceptionRoutedEventArgs.ErrorMessage}" );
Element?.SetIsLoading(false);
@@ -107,6 +118,11 @@ namespace Xamarin.Forms.Platform.WinRT
void UpdateAspect()
{
+ if (_disposed || Element == null || Control == null)
+ {
+ return;
+ }
+
Control.Stretch = GetStretch(Element.Aspect);
if (Element.Aspect == Aspect.AspectFill) // Then Center Crop
{
@@ -120,15 +136,40 @@ namespace Xamarin.Forms.Platform.WinRT
}
}
- async Task UpdateSource()
+ protected virtual async Task TryUpdateSource()
{
+ // By default we'll just catch and log any exceptions thrown by UpdateSource so we don't bring down
+ // the application; a custom renderer can override this method and handle exceptions from
+ // UpdateSource differently if it wants to
+
+ try
+ {
+ await UpdateSource().ConfigureAwait(false);
+ }
+ catch (Exception ex)
+ {
+ Log.Warning(nameof(ImageRenderer), "Error loading image: {0}", ex);
+ }
+ finally
+ {
+ ((IImageController)Element)?.SetIsLoading(false);
+ }
+ }
+
+ protected async Task UpdateSource()
+ {
+ if (_disposed || Element == null || Control == null)
+ {
+ return;
+ }
+
Element.SetIsLoading(true);
ImageSource source = Element.Source;
IImageSourceHandler handler;
if (source != null && (handler = Registrar.Registered.GetHandler<IImageSourceHandler>(source.GetType())) != null)
{
- Windows.UI.Xaml.Media.ImageSource imagesource = null;
+ Windows.UI.Xaml.Media.ImageSource imagesource;
try
{
@@ -138,10 +179,6 @@ namespace Xamarin.Forms.Platform.WinRT
{
imagesource = null;
}
- catch (Exception ex)
- {
- Log.Warning("Image Loading", $"Error updating image source: {ex}");
- }
// In the time it takes to await the imagesource, some zippy little app
// might have disposed of this Image already.
@@ -155,7 +192,7 @@ namespace Xamarin.Forms.Platform.WinRT
else
{
Control.Source = null;
- Element?.SetIsLoading(false);
+ Element.SetIsLoading(false);
}
}
}