【问题标题】:Exceptions when using Xamarin Android使用 Xamarin Android 时的异常
【发布时间】:2013-06-21 11:28:18
【问题描述】:

我最近开始学习使用 Xamarin Android 进行移动开发。我正在使用 VS 2012。我注意到当我打开一个 android 项目时,Debug -> Exceptions 下的所有异常都未选中。我认为这就是代码中抛出的异常没有以我在桌面开发中习惯的方式显示的原因。当我在 Debug->Exceptions 窗口中检查异常并尝试将解决方案部署到模拟器时,它失败了 - 没有错误,但应用程序没有在模拟器上启动。

所以我的问题是:使用 VS 2012 或 VS 2010 和模拟器为 Android 开发时这是正常行为吗?有没有办法以“正常方式”查看抛出的异常,而不仅仅是在输出窗口中。如果我使用实际的 Android 设备进行调试,情况会改变吗?

【问题讨论】:

    标签: c# android visual-studio-2012


    【解决方案1】:

    我的答案是

    为什么?

    关于大自然,您必须了解一件重要的事情 Android 中未处理的异常,在 Android 中没有…… 这是一个未捕获的异常,这意味着您无法“处理”它或 像在 .Net 环境中那样从它中恢复。

    Xamarin(Mono) 在内部“处理”那些未捕获的异常 用 try-catch 包围一切并提高 未处理的事件,但这不是重点。也很气馁 出于各种原因与 UI 进行交互。

    理论上,显示对话框有几种“变通方法” 给用户或重新启动应用程序,我不建议这样做 正在做。相反,您应该使用 try-catch 包围敏感区域 处理预期异常的子句,至于意外的 只需使用异常报告组件并在之后更新您的应用程序 分析报告的异常

    解释From

    您也可以像这样从应用程序中捕获未处理的异常

    创建一个类似名称的基础活动 ErrorActivity

    看看这个例子

    protected override void OnCreate(Bundle bundle)
     {
            //register error handlers
                        AppDomain.CurrentDomain.UnhandledException += ErrorHandler.CurrentDomainOnUnhandledException;
                        TaskScheduler.UnobservedTaskException += ErrorHandler.TaskSchedulerOnUnobservedTaskException;
      }
    

    在错误处理类中

    public static class ErrorHandler
        {
            /// <summary>
            ///     Tasks the scheduler on unobserved task exception.
            /// </summary>
            /// <param name="sender">The sender.</param>
            /// <param name="unobservedTaskExceptionEventArgs">
            ///     The <see cref="UnobservedTaskExceptionEventArgs" /> instance containing
            ///     the event data.
            /// </param>
            public static void TaskSchedulerOnUnobservedTaskException(object sender,
                UnobservedTaskExceptionEventArgs unobservedTaskExceptionEventArgs)
            {
                var newExc = new Exception("TaskSchedulerOnUnobservedTaskException",
                    unobservedTaskExceptionEventArgs.Exception);
                LogUnhandledException(newExc);
            }
    
            /// <summary>
            ///     Currents the domain on unhandled exception.
            /// </summary>
            /// <param name="sender">The sender.</param>
            /// <param name="unhandledExceptionEventArgs">
            ///     The <see cref="UnhandledExceptionEventArgs" /> instance containing the event
            ///     data.
            /// </param>
            public static void CurrentDomainOnUnhandledException(object sender,
                UnhandledExceptionEventArgs unhandledExceptionEventArgs)
            {
                var newExc = new Exception("CurrentDomainOnUnhandledException",
                    unhandledExceptionEventArgs.ExceptionObject as Exception);
                LogUnhandledException(newExc);
            }
    
            /// <summary>
            ///     Logs the unhandled exception.
            /// </summary>
            /// <param name="exception">The exception.</param>
            internal static void LogUnhandledException(Exception exception)
            {
                try
                {
                    string error =
                        $"Exception Caught:{DateTime.Now:F} The Error Message IS {exception.Message}\n\r full stack trace is {exception.ToString()} ";
    #if DEBUG
                    const string errorFileName = "errorlog.txt";
                    var libraryPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
                    // iOS: Environment.SpecialFolder.Resources
                    var errorFilePath = System.IO.Path.Combine(libraryPath, errorFileName);
                    System.IO.File.WriteAllText(errorFilePath, error);
                    Android.Util.Log.Error("Crash Report error not handled", ex.ToString());
        #else
                        // Log to Android Device Logging.
                        Android.Util.Log.Error("Crash Report", error);
        #endif
                    }
                    catch (Exception ex)
                    {
                        Android.Util.Log.Error("Crash Report error not handled", ex.ToString());
                        // just suppress any error logging exceptions
                    }
                }
            }
    

    现在您可以像这样从 ErrorActivity 继承所有活动

    Public class Fooactivity:ErrorActivity
    {
    }
    

    现在您可以在应用程序中处理错误..因此您可以从日志文件..或 android 设备日志记录监视器中获取错误日志..希望这会有所帮助...

    【讨论】:

      【解决方案2】:

      也许我不够清楚。 Visual Studio 中的代码执行确实中断了,但是在用于探索我在桌面编程时遇到的异常的标准窗口中,该窗口仅包含抛出异常的名称,一个复选框,用于在这种类型的情况下禁用代码中断抛出异常和中断、继续和忽略按钮。但我无法以桌面编程时可用的方式探索实际异常。

      Debug --&gt; Exceptions 对话框中,如果您单击Common Language Runtime ExceptionsThrown 复选框,您将获得对要解决的异常的更有意义的描述。

      显然,另一件大事是单击 Break 按钮并查看调用堆栈上的内容。

      【讨论】:

        【解决方案3】:

        我也是 Xamarin 的新手。简单的答案是不,这不是你应该期待的。

        如果应用程序在设备上运行时出现异常,它会在 Visual Studio 中中断。最好的办法是直接联系 Xamarin 或访问那里的论坛。

        【讨论】:

        • 感谢您的回答。也许我不够清楚。 Visual Studio 中的代码执行确实中断了,但是在用于探索我在桌面编程时遇到的异常的标准窗口中,该窗口仅包含抛出异常的名称,一个复选框,用于在这种类型的情况下禁用代码中断抛出异常和中断、继续和忽略按钮。但我无法以桌面编程时可用的方式探索实际异常。
        【解决方案4】:

        我能够深入研究未处理的异常:

        继续以下操作:

        1. 捕捉事件AppDomain.CurrentDomain.UnhandledException
        2. 如果您仔细观察,您会发现它基本上以某种方式翻译了 Java.Lang.Runtime 异常,因此如果您检查 ExceptionObject 属性,它应该会非常清楚地告诉您应用程序出了什么问题。就我而言,它给了我非常明确的信息,即我没有在我的 Fragment 中调用 base OnDestroyView

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-07-05
          • 1970-01-01
          • 2021-11-14
          • 1970-01-01
          • 2021-10-07
          相关资源
          最近更新 更多