AppMetrica Gradle Plugin

AppMetrica lets you collect information about native and Java crashes. You can analyze them in the Crashes report. See also Crashes/errors.

To reduce the size of an app, optimize the code during a release build.

If the code was compressed and obfuscated during the build of an Android application, information about crashes is transmitted in obfuscated form. To extract data for analysis from such crash logs, AppMetrica performs server-side deobfuscation.

To do this, upload the mapping files or debug symbols of SO files to AppMetrica, either automatically when building the app or manually via the web interface.

To send files, enable the AppMetrica Gradle Plugin.

Restrictions

  • The plugin is applied only to modules with com.android.application. It is not applied to com.android.library modules.

  • Upload mapping files if you use ProGuard or R8. If you don't compress or obfuscate the code, don't enable the plugin.

  • The plugin's operation depends on the versions of com.android.tools.build:gradle (AGP) and gradle. The plugin is compatible with the following versions:

    • com.android.tools.build:gradle from 7.2.0 to 8.13.+ (except for 8.0.+);
    • gradle from 7.4 to 9.2.1. We don't guarantee that the plugin will work with other versions.

    The plugin's functionality is not guaranteed when using Gradle 8.0 and AGP 7.4.* together.

  • For local builds, it is recommended to disable the plugin — this speeds up the build. Enable it only on CI. A convenient pattern is to control the enable flag through an environment variable:

    appmetrica {
        enable.set(providers.environmentVariable("CI").map { it == "true" }.orElse(false))
    }
    

Connecting the plugin

To enable the plugin:

  1. Add the following dependency to the Gradle root file:

    plugins {
        id("io.appmetrica.analytics") version "2.1.0" apply false
    }
    
    plugins {
        id "io.appmetrica.analytics" version "2.1.0" apply false
    }
    
    Enabling plugin using buildscript

    Add the following dependency to the Gradle root file:

    buildscript {
       repositories {
           mavenCentral()
       }
       dependencies {
           classpath("io.appmetrica.analytics:gradle:2.1.0")
       }
    }
    
    buildscript {
       repositories {
           mavenCentral()
       }
       dependencies {
           classpath 'io.appmetrica.analytics:gradle:2.1.0'
       }
    }
    
  2. Add the plugin and its configuration to the app's Gradle file:

    plugins {
        id("com.android.application")
        id("io.appmetrica.analytics")
    }
    
    appmetrica {
        postApiKey.set("Post Api key")
        enable.set(true)                                    // Optional
        offline.set(false)                                  // Optional
        mappingFile.set(file("path/to/mapping.txt"))        // Optional
        enableAnalytics.set(true)                           // Optional
        allowTwoAppMetricas.set(false)                      // Optional
        ndk {                                               // Optional
            enable.set(false)
            soFiles.from(file("path/to/so"))                // Optional
            additionalSoFiles.from(file("path/to/extra"))   // Optional
            addNdkCrashesDependency.set(true)               // Optional
        }
    }
    
    plugins {
        id 'com.android.application'
        id 'io.appmetrica.analytics'
    }
    
    appmetrica {
        postApiKey = "Post Api key"
        enable = true                                       // Optional
        offline = false                                     // Optional
        mappingFile = file("path/to/mapping.txt")           // Optional
        enableAnalytics = true                              // Optional
        allowTwoAppMetricas = false                         // Optional
        ndk {                                               // Optional
            enable = false
            soFiles.from(file("path/to/so"))                // Optional
            additionalSoFiles.from(file("path/to/extra"))   // Optional
            addNdkCrashesDependency = true                  // Optional
        }
    }
    

    Parameter

    Description

    postApiKey*

    Post API key. String.
    You can get the Post API key in the Settings section in AppMetrica. It's used to identify your app.

    If offline = true, the parameter is optional.

    Note on hierarchical configuration: the value must match across all sources where it is set. If different sources specify different values, the plugin logs an error and treats the key as not set (see Hierarchical configuration).

    enable

    Enables or disables the plugin for the given build variant. Boolean.
    If the plugin is disabled, the apk is not changed, mapping and symbols are neither collected nor uploaded, and resource generation is not performed.

    By default, true only for buildType = 'release', otherwise false.

    Supports hierarchical configuration (see Hierarchical configuration).

    offline

    Enables the offline mode. Boolean.

    Acceptable values:

    • true — Doesn't upload files to AppMetrica. Archives are placed in build/appmetrica/<variant>/result/, paths are written to the log. You can upload the archives manually via the web interface.
    • false — Automatically uploads mapping and symbols.

    The default value is false.

    Supports hierarchical configuration (see Hierarchical configuration).

    mappingFile

    Path to the mapping file. RegularFileProperty (in Kotlin DSL set via file("...")).

    The default value is the mapping file from the build (the OBFUSCATION_MAPPING_FILE AGP artifact). Override it only if you want to upload mapping from a non-standard location.

    Supports hierarchical configuration (see Hierarchical configuration).

    enableAnalytics

    Lets plugin usage statistics be sent to AppMetrica. Boolean.

    Acceptable values:

    • true — Sending statistics is enabled.
    • false — Sending statistics is disabled.

    The default value is true.

    allowTwoAppMetricas

    Behavior when two different AppMetrica libraries (io.appmetrica.analytics:analytics and com.yandex.android:mobmetricalib) are present in the project at the same time. Boolean.

    Acceptable values:

    • false — If both libraries are found, the build fails with an error.
    • true — The presence of both libraries is allowed, a warning is written to the log.

    The default value is false.

    Supports hierarchical configuration (see Hierarchical configuration).

    ndk

    This parameter is required to load symbols from the SO file to track native crashes.

    ndk.enable

    Enables or disables processing and uploading symbols from SO files. Boolean.

    If enabled, symbol processing and upload tasks run automatically after the build.

    The default value is false.

    Supports hierarchical configuration (see Hierarchical configuration).

    ndk.soFiles

    SO files to process. ConfigurableFileCollection. Use .from(...) to add files.

    By default, the plugin takes SO files from the MERGED_NATIVE_LIBS AGP artifact — this already includes src/main/jniLibs/** and the output of CMake/ndk-build.

    Override it if your SO files are in a non-standard location or the plugin can't find them.

    Hierarchical configuration behavior: collections from all sources are merged (see Hierarchical configuration).

    ndk.additionalSoFiles

    Additional SO files. ConfigurableFileCollection. Use .from(...) to add files.

    Unlike soFiles, it doesn't replace the default but extends it.

    Hierarchical configuration behavior: collections from all sources are merged.

    ndk.addNdkCrashesDependency

    Automatically add the io.appmetrica.analytics:analytics-ndk-crashes dependency to the <variant>Implementation configuration. Boolean.

    The default value is true.

    Supports hierarchical configuration (see Hierarchical configuration).

    Note

    If the ndk.enable parameter is enabled, symbol processing and upload tasks run automatically after the build. No additional manual configuration is required.

Hierarchical configuration

The plugin supports four configuration levels:

appmetrica {
    // Global configuration
    variants {
        create("<variantName>") {
            // Variant configuration
        }
    }
}

android {
    buildTypes {
        named("<buildTypeName>") {
            appmetrica {
                // buildType configuration
            }
        }
    }
    productFlavors {
        named("<flavorName>") {
            appmetrica {
                // flavor configuration
            }
        }
    }
}

Note

For each build variant, the plugin collects values from all levels and applies a resolution strategy to them — each parameter has its own. This is not the "usual" priority where "the top level wins" — the behavior depends on the parameter type.

enable, offline, ndk.enable, allowTwoAppMetricas, enableAnalytics, ndk.addNdkCrashesDependency

Logic: "disabling always wins".

  • If at least one source has the value false — the result is false.
  • Otherwise, if at least one source has the value true — the result is true.
  • Otherwise, the default value is used.

Example:

appmetrica {
    enable.set(true)
}

android {
    buildTypes {
       debug {
           appmetrica {
               enable.set(false)
           }
       }
    }
}

As a result, enable is false for debug and true for all other variants.

postApiKey

Logic: "the value must be unique".

  • If the parameter is set in only one source — that value is used.
  • If it is set in several sources with the same value — that value is used.
  • If different sources specify different values — the error Conflicting values for postApiKey is logged, and the default value (an empty string) is used. Upload then won't happen — the plugin additionally emits the warning postApiKey is not set.

Therefore, set postApiKey only in one place — usually in the global block or in the relevant flavor.

mappingFile

Logic: "priority lookup".

Source priority: global block > per-variant > per-buildType > the first configured flavor > default value (mapping from the build). The value from the first source where the parameter is set is used.

ndk.soFiles, ndk.additionalSoFiles

Logic: "collection merging".

All non-empty .from(...) from all levels are merged into a single collection. If the collection is not configured at any level — soFiles falls back to the AGP default, and additionalSoFiles falls back to an empty collection. To replace the default set of files, set soFiles.from(...) in one of the sources — the default is then not used.

Example

// Global settings for all variants
appmetrica {
    enableAnalytics.set(true)
}

android {
    buildTypes {
        release {
            // NDK symbol upload is needed only for release builds
            appmetrica {
                ndk {
                    enable.set(true)
                }
            }
        }
    }

    productFlavors {
        // Each flavor has its own key — for example, different apps for prod and dev
        create("prod") {
            appmetrica {
                postApiKey.set("prod-post-api-key")
            }
        }
        create("dev") {
            appmetrica {
                postApiKey.set("dev-post-api-key")
            }
        }
    }
}

// Per-variant: targeted override for a specific variant
appmetrica {
    variants.create("prodRelease") {
        ndk {
            additionalSoFiles.from(file("extra-symbols"))
        }
    }
}
// Global settings for all variants
appmetrica {
    enableAnalytics = true
}

android {
    buildTypes {
        release {
            // NDK symbol upload is needed only for release builds
            appmetrica {
                ndk {
                    enable = true
                }
            }
        }
    }

    productFlavors {
        // Each flavor has its own key — for example, different apps for prod and dev
        prod {
            appmetrica {
                postApiKey = "prod-post-api-key"
            }
        }
        dev {
            appmetrica {
                postApiKey = "dev-post-api-key"
            }
        }
    }
}

// Per-variant: targeted override for a specific variant
appmetrica {
    variants.create("prodRelease") {
        ndk {
            additionalSoFiles.from(file("extra-symbols"))
        }
    }
}

Tip

To find out which values the plugin actually applied to a variant, look at the build log: for each parameter, a line is written in the form Using value 'X' from <source> for <parameter> or Using default value '...' for ....

Plugin tasks

For each build variant <variant> (Release, ProdRelease, etc.), the plugin registers the following tasks:

Task name

Purpose

check<variant>AppMetricaDependencies

Checks that exactly one AppMetrica library is used in the project (see allowTwoAppMetricas).

create<variant>AppMetricaRes

Generates resources in build/appmetrica/<variant>/res/; the result is merged into the application resources.

zip<variant>AppMetricaFiles

Builds mapping.zip (info.txt + mapping).

upload<variant>AppMetricaMapping

Uploads mapping.zip to AppMetrica (in offline mode — skipped, the archive remains in result/).

generate<variant>AppMetricaNdkSymbols

Converts SO files to .ysym.

zip<variant>AppMetricaNdkFiles

Builds symbols.zip (info.txt + .ysym).

upload<variant>AppMetricaNdkSymbols

Uploads symbols.zip to AppMetrica.

Upload tasks are wired as finalizedBy on assemble<variant> and bundle<variant>. Therefore, a regular build (./gradlew assembleRelease or ./gradlew bundleRelease) automatically triggers the upload. You can run the upload manually like this:

./gradlew uploadReleaseAppMetricaMapping
./gradlew uploadReleaseAppMetricaNdkSymbols

Manual loading

For manual upload, you need to enable the plugin in offline = true mode. This is needed so that the plugin generates info.txt with meta information, by which the server will associate the archive with the build.

  1. In the app/build.gradle file, turn on offline mode:

    appmetrica {
        offline.set(true)
    }
    
    appmetrica {
        offline = true
    }
    

    In offline mode, the postApiKey parameter is optional.

  2. Build the desired variant of the application (for example, ./gradlew assembleRelease). Archives will appear in <appModule>/build/appmetrica/<variant>/result/:

    • mapping.zip — for Java crashes;
    • symbols.zip — for native crashes, if ndk.enable is enabled.
  3. In the AppMetrica interface, go to the app settings from the menu on the left.

  4. Go to the CrashesAndroid tab.

  5. Click Choose file and upload the desired archive.

Build errors and warnings

Errors that interrupt the build

  • IllegalStateException — Code obfuscation is not enabled. Enable ProGuard or R8.
  • HttpResponseException — The archive could not be uploaded. Check your internet connection and the correctness of postApiKey.
  • Dependency check error — Two AppMetrica libraries (io.appmetrica.analytics:analytics and com.yandex.android:mobmetricalib) are found in the project at the same time. Remove one of them or, temporarily, set allowTwoAppMetricas = true.

Warnings (the build does not fail, but upload may not happen)

These messages are important to monitor, especially on CI — they mean that something went wrong, but Gradle won't report it.

  • AppMetrica plugin is enabled for variant '<variant>' but postApiKey is not set. Upload will fail. Set postApiKey or enable offline mode. — Upload is enabled for the variant, but the key is empty. Set postApiKey or enable offline.
  • Conflicting values for postApiKey: ...postApiKey is set in different sources with different values. The plugin uses an empty key — the upload will fail. Set the key in only one place or synchronize the values.
  • Using default value '...' for <parameter> — The parameter is not set in any source, the default is used. Useful for debugging if it seems that a setting "did not apply".

If you encounter other errors, please contact technical support.

Learn more

If you didn't find the answer you were looking for, you can use the feedback form to submit your question. Please describe the problem in as much detail as possible. Attach a screenshot if possible.

Contact support Suggest an improvement for documentation