zoukankan      html  css  js  c++  java
  • Handle navigation exceptions in Prism for Xamarin

    If you're using the NavigationService in Prism, for Xamarin.Forms or simply Xamarin, like this :

    navigationService.NavigateAsync(uri, parameters);
    
    1

    you might notice native crashes with no information or whatsoever.

    This happens when during the loading of the page and/or the navigation to it an exception is thrown. In that case you actually won't see any exception, the app will just crash and you will spend hours looking for an answer.

    The reason for that is that the NavigateAsync function is "awaitable" and returns a INavigationResult :

    namespace Prism.Navigation
    {
        public interface INavigationResult
        {
            bool Success { get; }
    
            Exception Exception { get; }
        }
    
        public class NavigationResult : INavigationResult
        {
            public bool Success { get; set; }
    
            public Exception Exception { get; set; }
        }
    }
    
    12345678910111213141516

    In order to handle this exception here is what I do :

    Method extensions

    I extend NavigateAsync functions with a TryNavigateAsync equivalent. The role of it is to handle the result of the navigation once it's done.

    public static async Task TryNavigateAsync(this INavigationService navigationService, Uri uri, INavigationParameters parameters = null)
    {
        var result = await navigationService.NavigateAsync(uri, parameters);
        HandleNavigationResult(result);
    }
    
    public static async Task TryNavigateModallyAsync(this INavigationService navigationService, Uri uri, INavigationParameters parameters = null)
    {
        var result = await navigationService.NavigateAsync(uri, parameters, true);
        HandleNavigationResult(result);
    }
    
    public static async Task TryNavigateAsync(this INavigationService navigationService, string path, INavigationParameters parameters = null)
    {
        var result = await navigationService.NavigateAsync(path, parameters);
        HandleNavigationResult(result);
    }
    
    public static async Task TryNavigateModallyAsync(this INavigationService navigationService, string path, INavigationParameters parameters = null)
    {
        var result = await navigationService.NavigateAsync(path, parameters, true);
        HandleNavigationResult(result);
    }
    
    public static async Task TryNavigateBackAsync(this INavigationService navigationService, INavigationParameters parameters = null)
    {
        var result = await navigationService.GoBackAsync(parameters);
        HandleNavigationResult(result);
    }
    
    1234567891011121314151617181920212223242526272829

    That enables you to use this line instead :

    // navigationService.NavigateAsync(uri, parameters);
    navigationService.TryNavigateAsync(uri, parameters);
    
    12

    Handle INavigationResult

    You want to test if your navigation was a success and, if not, do something with that exception :

    private static void HandleNavigationResult(INavigationResult navigationResult)
    {
        if (!navigationResult.Success)
        {
            Exception ex = new InvalidNavigationException();
            if (navigationResult.Exception != null)
                ex = navigationResult.Exception;
            SetMainPageFromException(ex);
        }
    }
    
    12345678910

    I created a new Exception for better logging purposes : InvalidNavigationException(), but if the inner navigation is given by Prism I will used the Prism one.

    Display the exception or throw it

    You can simply throw that exception if you want to. You might also just display it to yourself or in debug mode. Here is a little snippet to display that exception :

    private static void SetMainPageFromException(Exception ex)
    {
        var layout = new StackLayout
        {
            Padding = new Thickness(40)
        };
        layout.Children.Add(new Label
        {
            Text = ex?.GetType()?.Name ?? "Unknown Error encountered",
            FontAttributes = FontAttributes.Bold,
            HorizontalOptions = LayoutOptions.Center
        });
    
        layout.Children.Add(new ScrollView
        {
            Content = new Label
            {
                Text = $"{ex}",
                LineBreakMode = LineBreakMode.WordWrap
            }
        });
    
        PrismApplicationBase.Current.MainPage = new ContentPage
        {
            Content = layout
        };
    }
    
    123456789101112131415161718192021222324252627

    See the sample of all the code above being used in my Xamarin Developer Sample :

  • 相关阅读:
    Libcurl
    Inno Setup教程
    APICloud平台的融云2.0集成
    关于mysql建立索引 复合索引 索引类型
    linux恢复误删除文件-extundelete
    OpenStack QA
    Android之应用程序怎样调用支付宝接口
    NYOJ 22 素数求和问题
    Mycat(5):聊天消息表数据库按月分表实践,平滑扩展
    opencv对图像进行边缘及角点检測
  • 原文地址:https://www.cnblogs.com/mschen/p/12181401.html
Copyright © 2011-2022 走看看