记录 Xamarin 未处理(Android 未捕获)异常

Logging Xamarin unhandled (Android uncaught) exceptions

我想记录未处理的异常,但我看到关于是否可行以及如何可行的相互矛盾的信息。

我知道 Xamarin 引发了一个 AndroidEnvironment.UnhandledExceptionRaiserAppDomain.CurrentDomain.UnhandledException 事件,我可以订阅这个事件,但我的印象是 Android 正在终止我的进程,而且我无权访问 Android.Utils.Log 或文件系统。

如果您查看 Xamarin 的 AdvancedAppLifecycleDemos/HandlingCrashes/App.cs,就会发现一个令人信服的论点,即您无法记录此异常。

    /// <summary>
    /// When app-wide unhandled exceptions are hit, this will handle them. Be aware however, that typically
    /// android will be destroying the process, so there's not a lot you can do on the android side of things,
    /// but your xamarin code should still be able to work. so if you have a custom err logging manager or 
    /// something, you can call that here. You _won't_ be able to call Android.Util.Log, because Dalvik
    /// will destroy the java side of the process.
    /// </summary>
    protected void HandleUnhandledException(object sender, UnhandledExceptionEventArgs args)
    {
        Exception e = (Exception)args.ExceptionObject;

        // log won't be available, because dalvik is destroying the process
        //Log.Debug (logTag, "MyHandler caught : " + e.Message);
        // instead, your err handling code shoudl be run:
        Console.WriteLine("========= MyHandler caught : " + e.Message);
    }

那么如何记录未处理的异常?

Xamarin Insights 是您所需要的:https://xamarin.com/insights

With Xamarin Insights you can see a complete overview of any crashes and identify what type of issues and warnings that are occurring in your app

当 Xamarin Studio 5.10 最终版本发布时,Insights 也将被集成 (Read More)。

Xamarin Insights、HockeyApp 或其他崩溃记录器会在应用程序完成进程之前以某种方式保存崩溃数据。一旦应用程序重新启动,它们就会将数据发送到服务器(由于进程正在被终止,它们无法立即发送)。所以这是完全可能的。虽然我不确定他们是将崩溃数据保存到设备存储(最有可能)还是本地 SQLite 数据库。

这是 HockeyApp 用于捕获未处理的异常的代码。它可以给你一些想法:

AndroidEnvironment.UnhandledExceptionRaiser += (sender, args) =>
{
    TraceWriter.WriteTrace(args.Exception);
    args.Handled = true;
};

AppDomain.CurrentDomain.UnhandledException += (sender, args) => 
    TraceWriter.WriteTrace(args.ExceptionObject);

// Wire up the unobserved task exception handler
TaskScheduler.UnobservedTaskException +=  (sender, args) =>
    TraceWriter.WriteTrace(args.Exception);

我建议尝试使用这些方法中的任何一种将文本文件写入本地存储