Jason Steele
Jason Steele

Reputation: 1606

crash reporting in MonoTouch and MonoDroid

I'm writing a cross platform application using Mvvmcross, Mono for Android and MonoTouch. In the Java Android app I am porting I used ACRA to provide crash reports and ad-hoc reports. These reports were sent to our server over an HTTP Post.

Are there any crash reporting plugins for Mvvmcross? Can the Mono* community recommend any crash reporting libraries?

If there doesn't seem to be anything, how are other developers dealing with this? How are they capturing untrapped application exceptions and Android ANRs so that a report can be fired off?

Upvotes: 3

Views: 1244

Answers (3)

Dan Abramov
Dan Abramov

Reputation: 268255

We're using HockeyApp iOS SDK (I believe they have one for Android too).
We also employ this fix because it's essential to crash reporters working in MonoTouch.

Upvotes: 0

mironych
mironych

Reputation: 2978

Previously I worked on MonoDroid app and built Crasher as port of ACRA. But because of some features of Mono and in particular .NET, some functions of ACRA can't be implemented in MonoDroid. Will be glad if it will help you.

Upvotes: 1

Stuart
Stuart

Reputation: 66882

The only experience I've had in this area is with Flurry - and we only used that for analytics, not for crash reporting.

Basically what we did was log all important events from the ViewModel using an IAnalytics interface, and then each platform supplied an implementation of IAnalytics like:

WP7:

public class FlurryAnalytics : IAnalytics
{
    public const string ApiKeyValue = "--- your key ---";

    public void StartSession()
    {
        FlurryWP7SDK.Api.StartSession(ApiKeyValue);
    }

    public void LogEvent(string eventName)
    {
        FlurryWP7SDK.Api.LogEvent(eventName);
    }
}

Touch (used with bindings like https://github.com/kevinmcmahon/monotouch-libs/blob/master/FlurryAnalytics/flurry.cs):

public class FlurryAnalytics : IAnalytics
{
    public const string ApiKeyValue = "37SHD8L8VATPBS88AMHU";

    public void StartSession()
    {
        FlurryAPI.StartSession (ApiKeyValue);
    }

    public void LogEvent(string eventName)
    {
        FlurryAPI.LogEvent(eventName);
    }
}

Android (a bit more complicated - it needs a hook from every start/stop of an activity):

public class FlurryAnalytics : IAnalytics, IAndroidActivityTracker
{
    public const string ApiKeyValue = "--- your key ---";

    private readonly IntPtr _flurryClass;
    private readonly IntPtr _flurryOnStartSession;
    private readonly IntPtr _flurryOnEndSession;
    private readonly IntPtr _flurryLogEvent;

    public FlurryAnalytics()
    {
        _flurryClass = JNIEnv.FindClass("com/flurry/android/FlurryAgent");
        _flurryOnStartSession = JNIEnv.GetStaticMethodID(_flurryClass, "onStartSession",
                                                         "(Landroid/content/Context;Ljava/lang/String;)V");
        _flurryOnEndSession = JNIEnv.GetStaticMethodID(_flurryClass, "onEndSession", "(Landroid/content/Context;)V");
        _flurryLogEvent = JNIEnv.GetStaticMethodID(_flurryClass, "logEvent", "(Ljava/lang/String;)V");
    }

    public void StartSession()
    {
        // not used in Android - Android relies on Activity tracking instead
    }

    public void LogEvent(string eventName)
    {
        ExceptionSafe(() => JNIEnv.CallStaticVoidMethod(_flurryClass, _flurryLogEvent, new JValue(new Java.Lang.String(eventName))));
    }

    private static void ExceptionSafe(Action action)
    {
        try
        {
            action();
        }
        catch (ThreadAbortException)
        {
            throw;
        }
        catch (Exception exception)
        {
            UITrace.Trace("Exception seen in calling Flurry through JNI " + exception.ToLongString());
        }
    }

    public void OnStartActivity(Activity activity)
    {
        ExceptionSafe(() => JNIEnv.CallStaticVoidMethod(_flurryClass, _flurryOnStartSession, new JValue(activity), new JValue(new Java.Lang.String(ApiKeyValue))));
    }

    public void OnStopActivity(Activity activity)
    {
        ExceptionSafe(() => JNIEnv.CallStaticVoidMethod(_flurryClass, _flurryOnEndSession, new JValue(activity)));
    }
}

From the Flurry documentation and from some blogs out there, I believe this could be extended to include crash reporting:

But without trying it, I don't know how well it would work inside MonoDroid and MonoTouch.

Upvotes: 1

Related Questions