Exceptions when using Xamarin Android

2019-01-20 10:25发布

I recently started to learn mobile development using Xamarin Android. I am using VS 2012. I noticed that when I open an android project that all exceptions under Debug -> Exceptions are unchecked. I thought that is the reason that exceptions thrown in code are not shown in a way to which I am used to from desktop development. When I checked the exceptions in Debug->Exceptions window and tried to deploy the solution to the emulator it failed - there were no errors but the application does not start on the emulator.

So my question is: Is that normal behavior when developing for Android using VS 2012 or VS 2010 and the emulator? Is there any way to see the thrown exceptions in a 'normal way' not just in output window. Would that change if I used an actual Android device for debugging?

4条回答
时光不老,我们不散
2楼-- · 2019-01-20 10:43

I was able to dig into Unhandled exception:

Proceed following:

  1. Catch event AppDomain.CurrentDomain.UnhandledException
  2. If you look closely, you will see that its basically somehow translated Java.Lang.Runtime exception so if you examine the ExceptionObject property it should give you very clear message what is wrong with app. In my case it gave me very clear message that I am not calling base OnDestroyView in my Fragment
查看更多
Ridiculous、
3楼-- · 2019-01-20 10:44

Maybe I wasn't clear enough. The code execution in visual studio does break, but instad of a standard window used to explore the exception which I get when programming for desktop, the window contains only the name of the thrown exception, a checkbox to disable the code break when this type of exception is thrown and Break, Continue and Ignore buttons. But I can not explore the actual exception in a way available when programming for desktop.

In the Debug --> Exceptions dialog box, if you click the Thrown checkbox for Common Language Runtime Exceptions you will get a more meaningful description of the exception to be resolved.

enter image description here

Obviously the other big thing is clicking the Break button and seeing what is on the call stack.

查看更多
姐就是有狂的资本
4楼-- · 2019-01-20 10:50

I'm new to Xamarin as well. The simple answer is no this is not what you should expect.

If I get an exception when the application is running on the device it breaks in Visual Studio. Best bet is to contact Xamarin direct or go on there forums.

查看更多
做自己的国王
5楼-- · 2019-01-20 10:51

My Answer Is NO

Why?

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

Explation From

also you could catch the unhadled exception from app Like this

Create a base activity like name ErrorActivity

look at this example

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

In error handler class

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
                }
            }
        }

Now you could inherit the all activitys from ErrorActivity like this

Public class Fooactivity:ErrorActivity
{
}

Now you can handled the error in app..So you get the error log from log File.. or android device logging monitor..Hope this helps...

查看更多
登录 后发表回答