Back to Diagnostics|GatiFlow Android SDKv1.0.0
InstallationInitializationCrash ReportingAnalyticsUser IdentityAdvanced ConfigAPI ReferenceTroubleshooting

Android SDK

Automatically capture crashes, ANRs, and custom analytics events from your Android app. One initialization line. No configuration required.

minSdk 21Kotlin / JavaOkHttp 4No Reflection

Installation

The SDK is distributed via JitPack — free, no account needed.

Step 1 — Add JitPack repository

In your project-level settings.gradle.kts, add JitPack inside dependencyResolutionManagement:

kotlin
dependencyResolutionManagement {
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://jitpack.io") }  // add this
    }
}

Using the legacy Groovy DSL? Add to your project-level build.gradle instead:

groovy
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}

Step 2 — Add the dependency

In your app-level build.gradle.kts:

kotlin
dependencies {
    implementation("com.github.dmsyudha:gatiflow-android:v1.0.0")
}

Or using the legacy Groovy DSL:

groovy
dependencies {
    implementation 'com.github.dmsyudha:gatiflow-android:v1.0.0'
}

The SDK requires INTERNETpermission. This is automatically merged into your app's manifest via manifest merger.

Initialization

Initialize in your Application.onCreate() — not in an Activity. This ensures crashes that happen before any Activity starts are still captured.

kotlin
class MyApp : Application() {
    override fun onCreate() {
        super.onCreate()

        GatiFlow.start(
            app = this,
            appToken = "mhub_YOUR_APP_TOKEN",
            services = listOf(Crashes::class.java, Analytics::class.java),
        )
    }
}

Where to find your token: Go to Settings → API Tokens in your GatiFlow dashboard and create a token scoped to your app.

Register Application class

Make sure your custom Application class is declared in AndroidManifest.xml:

xml
<application
    android:name=".MyApp"
    ...
/>

Crash Reporting

The Crashes service installs a global uncaught exception handler and an ANR watchdog automatically. No extra code is required for unhandled crashes.

Handled exceptions

Use trackError to report exceptions you catch and recover from:

kotlin
try {
    riskyOperation()
} catch (e: Exception) {
    GatiFlow.crashes?.trackError(e)
    // or with metadata:
    GatiFlow.crashes?.trackError(e, metadata = mapOf(
        "screen" to "CheckoutScreen",
        "userId" to currentUser.id,
    ))
}

ANR detection

ANRs are detected automatically when the main thread is blocked for more than 5 seconds (configurable). The stack trace at the time of the ANR is captured and reported as a handled error.

Offline behaviour

Crashes are serialized to disk immediately on the crashing thread — before any network call. On the next app launch, pending crashes are flushed to the API automatically. Up to 50 crashes are queued (configurable via Config.Builder.maxCrashQueueSize).

Disable crash reporting

kotlin
// Opt out (e.g. based on user consent)
GatiFlow.crashes?.setEnabled(false)

// Re-enable
GatiFlow.crashes?.setEnabled(true)

Analytics

Track custom events with optional properties. Events are batched and flushed automatically.

Track an event

kotlin
// Simple event
GatiFlow.analytics?.trackEvent("app_open")

// Event with properties (String, Number, Boolean values supported)
GatiFlow.analytics?.trackEvent("purchase_completed", mapOf(
    "product_id" to "prod_abc123",
    "price" to 9.99,
    "currency" to "USD",
))

Flush manually

kotlin
// Force-flush before a critical transition (e.g. logout)
GatiFlow.analytics?.flush()

Session tracking

Sessions are tracked automatically using ActivityLifecycleCallbacks. A new session starts when the app comes to the foreground and ends when it fully backgrounds. Each event is associated with the active session automatically.

User Identity

Associate a user ID with all crashes and events. Call this after login and clear it on logout:

kotlin
// On login
GatiFlow.setUserId(currentUser.id)

// On logout
GatiFlow.setUserId(null)

The user ID is persisted to disk and survives app restarts. It is attached to every crash and event until cleared.

Advanced Configuration

kotlin
val config = Config.Builder(appToken = "mhub_YOUR_TOKEN")
    // Point at a self-hosted instance
    .baseUrl("https://your-domain.com")

    // Enable verbose SDK logging (disable in production)
    .debugLogging(BuildConfig.DEBUG)

    // Max crashes to queue when offline (default: 50)
    .maxCrashQueueSize(100)

    // Max events per batch before force-flush (default: 100)
    .maxEventBatchSize(200)

    // How often to flush events to the API in ms (default: 30s)
    .flushIntervalMs(15_000)

    // ANR detection threshold in ms (default: 5s, min: 1s)
    .anrTimeoutMs(3_000)

    .build()

GatiFlow.start(this, config, listOf(Crashes::class.java, Analytics::class.java))

Custom service

Extend GatiFlowService to create your own service and register it alongside the built-in ones:

kotlin
class MyFeatureService : GatiFlowService() {
    override fun onCreate(app, config, deviceInfo, storage, http) {
        // inject dependencies
    }
    override fun onStart() { /* begin work */ }
    override fun onStop() { /* release resources */ }
}

GatiFlow.start(this, config, listOf(
    Crashes::class.java,
    Analytics::class.java,
    MyFeatureService::class.java,
))

API Reference

MethodDescription
GatiFlow.start(app, appToken, services)Initialize the SDK with a token and service list
GatiFlow.start(app, config, services)Initialize with a full Config object
GatiFlow.setUserId(id)Set / clear the user identity
GatiFlow.crashesAccess the Crashes service
GatiFlow.analyticsAccess the Analytics service
GatiFlow.stop()Stop all services (testing / opt-out)
Crashes.trackError(t, metadata?)Report a handled exception
Crashes.setEnabled(bool)Enable or disable crash reporting
Analytics.trackEvent(name, properties?)Record a custom event
Analytics.flush()Force-flush the event queue
Analytics.setEnabled(bool)Enable or disable analytics

Troubleshooting

No crashes appearing in the dashboard

Check that your app token is correct and the device has internet access. Enable debug logging with .debugLogging(true) to see SDK output in Logcat (tag: GatiFlow).

GatiFlow.start() is called but crashes field is null

You must pass Crashes::class.java in the services list. GatiFlow.crashes returns null if the service was not registered.

Crashes appear with missing stack traces

Make sure your app's ProGuard/R8 config keeps SourceFile and LineNumberTable attributes, and that you upload a mapping file to your build provider.

ANR detector fires too often in debug builds

Increase the ANR timeout via .anrTimeoutMs(10_000) for debug, or disable it by not including Crashes in debug builds.

GatiFlow Android SDK v1.0.0← Back to Crash Diagnostics