c# - 使用 Xamarin Android 时出现异常

标签 c# android visual-studio-2012

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

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

最佳答案

我的回答是

为什么?

There is one important thing you have to understand about the nature of an Unhandled exception in Android, there isn't one.... in Android it's an Uncaught exception which means you can't "handle" it or recover from it like you maybe would in a .Net environment.

Xamarin(Mono) internally "handles" those uncaught exceptions by surrounding literally everything with try-catch and raising the Unhandled event but that is besides the point. It is also discouraged to interact with the UI as well for various reasons.

Theoretically there are several "workarounds" for displaying a dialog to the user or restarting the app, none of which I'd recommend on doing. Instead you should surround sensitive areas with try-catch clauses to handle expected exceptions, as for the unexpected one's just use an exception reporting component and update your app after analyzing the reported exceptions

解释 From

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

创建一个基本 Activity ,如名称 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 继承所有 Activity

Public class Fooactivity:ErrorActivity
{
}

现在您可以处理应用程序中的错误了。所以您可以从日志文件中获取错误日志。

关于c# - 使用 Xamarin Android 时出现异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17234155/

相关文章:

android - 安卓二维码阅读器

WPF - 选项卡中的 xaml 滚动条

c# - 如何通过 XmlElement 名称从序列化中排除类字段?

c# - 在 MVC 中使用 DBCONTEXT 类的正确方法

java - 从 ActionBar 调用新 Activity

java - 将值从 MainActivity 传递到自定义 ListView 适配器类

c++ - 为 C 和 C++ 安装 MessagePack 实现时出现链接器错误

visual-studio-2012 - 为什么 Visual Studio 会重命名我的项目?

c# - 异常处理 ASP .NET Core MVC 6

c# - LInq left join with multiple condition in on 子句