Skip to content

tpurtell/AndroidHockeyApp

Repository files navigation

This is a binding of HockeyApp for Android (SDK version 3.0.2) for use with Xamarin.Android. 

It includes an additional class, TraceWriter, which allows you to log exceptions that come from .NET into HockeyApp.  Exceptions are reported to HockeyApp and are properly grouped.  You will see both java and c# based exceptions.

***** NOTE: HockeyApp is quite picky about the format that exceptions are reported in, so there is a significant transformation going on inside TraceWriter to make the exceptions group properly. ****
- The arguments string is transformed so that it can look like a filename and line number string (not tested if this is strictly necessary, but done out of caution)
- AggregateExceptions have only the most inner exception reported.  This means you should log the full exception and report it via the Description property of a custom CrashManagerListener along with any other log you might want to know about
- Your package name is prepended to the method fullname for anything that does not start with java/mono/android/system.  You can customize it to match just some namespaces, with the TraceWriter.AppNamespaces static property.  Disable it by specifying a blank list if you have a traditional java namespace set up for your app

I use it as follows, if you have other suggestions, I would love to hear ([email protected]).

The tricky thing is that you have to integrate it into how you work with Tasks, since the .NET uncaught task exception only reports when a Task has an exception and is finalized.  Thanks to adestis-ds, I learned that you can also intercept uncaught .NET exceptions running inside java code before they are converted to Java exceptions using AndroidEnvironment.UnhandledExceptionRaiser.

I have an auxiliary class that is a utility for catching exceptions on Tasks.

    public static class ExceptionSupport
    {
        public static void LogAndIgnore(Task task)
        {
            Console.WriteLine("Task failed: {0}", task.Exception);
        }
        public static void ReportAndExit(Task task)
        {
            Console.WriteLine("Task failed: {0}", task.Exception);
            UncaughtTaskExceptionHandler(task.Exception);
            Process.GetCurrentProcess().Kill();
        }
        public static Action<object> UncaughtTaskExceptionHandler;
        public static Task HandleExceptions(this Task task)
        {
            return task.HandleExceptions(ReportAndExit);
        }
        public static Task HandleExceptions(this Task task, Action<Task> handler)
        {
            return task.ContinueWith(handler,
                                TaskContinuationOptions.OnlyOnFaulted |
                                TaskContinuationOptions.ExecuteSynchronously);
        }
    }
    
Now when I do Task.Factory.StartNew(Foo), I make sure to follow it with .HandleExceptions().  Or if I don't care about the task's result, then .HandleExceptions(ExceptionSupport.LogAndIgnore).

Then I have a some code in my BaseActivity class which provides general instrumentation across my app.  Here we want to ensure that the crash handler is **always** registered even if the app crashes and Android starts up just the current activity again (not some root launcher activity that your home screen icon invokes).

    public abstract class BaseActivity : WhateverActivityBaseYouLike
    {
        private static bool _CrashHandlerRegistered = false;
        protected override void OnResume ()
        {
            base.OnResume ();
            if (!_CrashHandlerRegistered)
            {
                _CrashHandlerRegistered = true;
                CrashManager.Register(this, PlatformUtils.HockeyApplicationId);
                //copy build properties into c# land so that the handler won't crash accessing java
                TraceWriter.InitializeConstants();
				//TraceWriter.Initialize(listener); // instead of InitializeConstants: if you want things like user/contact/description

                AndroidEnvironment.UnhandledExceptionRaiser += (sender, args) => 
					{
						TraceWriter.WriteTrace(args.Exception);
						args.Handled = true;
					};
                AppDomain.CurrentDomain.UnhandledException +=
                    (sender, args) => TraceWriter.WriteTrace(args.ExceptionObject);
                TaskScheduler.UnobservedTaskException += (sender, args) => TraceWriter.WriteTrace(args.Exception);
                ExceptionSupport.UncaughtTaskExceptionHandler = TraceWriter.WriteTrace;
            }
    ...
        

About

hockeyapp binding for xamarin.android

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •  

Languages