使用Xamarin Android时的例外情况

时间:2013-06-21 11:28:19

标签: c# android visual-studio-2012

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

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

4 个答案:

答案 0 :(得分:5)

  

也许我不够清楚。 Visual Studio中的代码执行确实中断了,但是标准窗口的instad用于探索在为桌面编程时获得的异常,该窗口仅包含抛出异常的名称,该复选框用于禁用此类型的代码中断抛出异常并按下Break,Continue和Ignore按钮。但是,我无法以桌面编程的方式探索实际的异常。

Debug --> Exceptions对话框中,如果您点击Thrown的{​​{1}}复选框,您将获得有关要解决的例外的更有意义的说明。

enter image description here

显然另一件大事就是点击Break按钮查看调用堆栈中的内容。

答案 1 :(得分:5)

我的答案是

为什么?

  

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

     

Xamarin(Mono)在内部“处理”那些未被捕获的异常   几乎所有的东西都有try-catch和提升   未处理的事件,但除此之外。它也是气馁的   也可以出于各种原因与UI进行交互。

     

理论上,有几个“解决方法”用于显示对话框   对用户或重新启动应用程序,我都不推荐   这样做。相反,你应该用try-catch包围敏感区域   处理预期异常的条款,就像意外的异常一样   只需使用异常报告组件并在之后更新您的应用   分析报告的例外情况

解释From

你也可以从app这样的

中捕获未解决的异常

创建名称 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
{
}

现在你可以在app中处理错误了。所以从日志文件中获取错误日志..或者android设备日志监视器。希望这有帮助...

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

我能够深入了解未处理的异常:

继续以下:

  1. Catch event AppDomain.CurrentDomain.UnhandledException
  2. 如果你仔细观察,你会发现它基本上以某种方式翻译了Java.Lang.Runtime异常,所以如果你检查ExceptionObject属性,它应该给你非常清楚的消息app有什么问题。在我的情况下,它给了我非常明确的信息,即我没有在OnDestroyView
  3. 中调用Fragment