首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Xamarin跨平台的全局异常处理

Xamarin跨平台的全局异常处理
EN

Stack Overflow用户
提问于 2016-09-15 12:57:00
回答 2查看 27.5K关注 0票数 34

请告诉我如何处理Xamarin跨平台项目中的全局异常(不会导致App崩溃)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-09-15 14:34:47

据我所知,没有一种'Xamarin.Forms‘的方式。你需要连接到Android和iOS,你可以做的就是创建一个方法,以同样的方式处理它们。

关于这一点的一个很好的post是由Peter Norman写的。他描述说,要在安卓中实现它,你可以在你的MainActivity.cs中做到这一点。

代码语言:javascript
复制
// In MainActivity
protected override void OnCreate(Bundle bundle)
{
    base.OnCreate(bundle);  

    AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
    TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;  

    Xamarin.Forms.Forms.Init(this, bundle);  
    DisplayCrashReport();  

    var app = new App();  
    LoadApplication(app);
}  

‪#‎region‬ Error handling
private static void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs unobservedTaskExceptionEventArgs)
{
    var newExc = new Exception("TaskSchedulerOnUnobservedTaskException", unobservedTaskExceptionEventArgs.Exception);
    LogUnhandledException(newExc);
}  

private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
    var newExc = new Exception("CurrentDomainOnUnhandledException", unhandledExceptionEventArgs.ExceptionObject as Exception);
    LogUnhandledException(newExc);
}  

internal static void LogUnhandledException(Exception exception)
{
    try
    {
        const string errorFileName = "Fatal.log";
        var libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // iOS: Environment.SpecialFolder.Resources
        var errorFilePath = Path.Combine(libraryPath, errorFileName);  
        var errorMessage = String.Format("Time: {0}\r\nError: Unhandled Exception\r\n{1}",
        DateTime.Now, exception.ToString());
        File.WriteAllText(errorFilePath, errorMessage);  

        // Log to Android Device Logging.
        Android.Util.Log.Error("Crash Report", errorMessage);
    }
    catch
    {
        // just suppress any error logging exceptions
    }
}  

/// <summary>
// If there is an unhandled exception, the exception information is diplayed 
// on screen the next time the app is started (only in debug configuration)
/// </summary>
[Conditional("DEBUG")]
private void DisplayCrashReport()
{
    const string errorFilename = "Fatal.log";
    var libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
    var errorFilePath = Path.Combine(libraryPath, errorFilename);

    if (!File.Exists(errorFilePath))
    {
        return; 
    }

    var errorText = File.ReadAllText(errorFilePath);
    new AlertDialog.Builder(this)
        .SetPositiveButton("Clear", (sender, args) =>
        {
            File.Delete(errorFilePath);
        })
        .SetNegativeButton("Close", (sender, args) =>
        {
            // User pressed Close.
        })
        .SetMessage(errorText)
        .SetTitle("Crash Report")
        .Show();
} 

‪#‎endregion‬

对于iOS,您可以在您的AppDelegate.cs中添加如下代码。

代码语言:javascript
复制
//iOS: Different than Android. Must be in FinishedLaunching, not in Main.
// In AppDelegate
public override bool FinishedLaunching(UIApplication uiApplication, NSDictionary options)
{
    AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
    TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;  
    // Rest of your code...
}  

/// <summary>
// If there is an unhandled exception, the exception information is diplayed 
// on screen the next time the app is started (only in debug configuration)
/// </summary>
[Conditional("DEBUG")]
private static void DisplayCrashReport()
{
    const string errorFilename = "Fatal.log";
    var libraryPath = Environment.GetFolderPath(Environment.SpecialFolder.Resources);
    var errorFilePath = Path.Combine(libraryPath, errorFilename);

    if (!File.Exists(errorFilePath))
    {
        return;
    }

    var errorText = File.ReadAllText(errorFilePath);
    var alertView = new UIAlertView("Crash Report", errorText, null, "Close", "Clear") { UserInteractionEnabled = true };
    alertView.Clicked += (sender, args) =>
    {
        if (args.ButtonIndex != 0)
        {
            File.Delete(errorFilePath);
        }
    };
    alertView.Show();
}

它还包括在调试应用程序时显示日志的能力。当然,您可以实现自己的日志记录或处理方法。您可以考虑的一件事是HockeyApp。这在默认情况下处理未处理的异常,并将它们发送回您,以及其他事情。

更新,因为这仍然可以在谷歌上找到:对于崩溃报告和分析,你现在想要开始关注App Center。这是HockeyApp和Xamarin Insights的演变(包括构建、分发和推送通知),现在成为与应用程序相关的所有任务的仪表盘,而不仅仅是Xamarin。

对于UWP和WinPhone 8.1,在Application对象中应该有一个UnhandledException处理程序。有关更多信息,请查看this answer。我引述如下:

XAML对于基于

的应用程序,您可以使用UnhandledException;但是,它只捕获通过XAML (UI)框架出现的异常,并且即使在InnerException中,您也不总是能够获得大量关于根本原因的信息。

Windows8.1的更新:UnhandledException还将捕获由异步void方法创建的异常。在Windows8中,这样的异常只会使应用程序崩溃。LunarFrog在他们的网站上有一个很好的discussion

基本上,您应该在App.xaml.csthis.UnhandledException += (o, s) => {}中的App()构造函数中添加一个事件处理程序。

票数 68
EN

Stack Overflow用户

发布于 2021-11-11 23:27:47

这就是我为xamarin forms、Android全局异常处理和应用程序崩溃所做的事情。

此解决方案将同时处理后台和前台异常。

代码语言:javascript
复制
AppDomain.CurrentDomain.UnhandledException += (s,e)=>
{
    System.Diagnostics.Debug.WriteLine("AppDomain.CurrentDomain.UnhandledException: {0}. IsTerminating: {1}", e.ExceptionObject, e.IsTerminating);
};

AndroidEnvironment.UnhandledExceptionRaiser += (s, e) =>
{
    System.Diagnostics.Debug.WriteLine("AndroidEnvironment.UnhandledExceptionRaiser: {0}. IsTerminating: {1}", e.Exception, e.Handled);
    e.Handled = true;
};

因此,对于这两种类型的异常,我有不同的行为:

前景:

背景:

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39503390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档