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 tocom.android.librarymodules. -
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:gradlefrom7.2.0to8.13.+(except for8.0.+);- gradle from
7.4to9.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.0and AGP7.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
enableflag through an environment variable:appmetrica { enable.set(providers.environmentVariable("CI").map { it == "true" }.orElse(false)) }
Connecting the plugin
To enable the plugin:
-
Add the following dependency to the Gradle root file:
plugins { id("io.appmetrica.analytics") version "2.1.0" apply false }Enabling plugin using
buildscriptAdd the following dependency to the Gradle root file:
buildscript { repositories { mavenCentral() } dependencies { classpath("io.appmetrica.analytics:gradle:2.1.0") } } -
Add the plugin and a minimal configuration to the app's Gradle file:
plugins { id("com.android.application") id("io.appmetrica.analytics") } appmetrica { postApiKey.set("Post Api key") ndk { enable.set(true) // Optional. Enable if your project has native code and you need native crashes } }The rest of the parameters and their default values are described in Plugin parameters.
Common tasks
In the typical case, you don't need to change any settings: enable defaults to true only for buildType = 'release', and ndk.enable defaults to false (enable it only if your project has native code and you need native crashes). So for a project without obfuscation outside of release and without NDK symbols, the plugin already works optimally out of the box.
Collect mapping and NDK symbols for a separate non-release buildType without spending the upload quota
This is needed, for example, if a separate non-release buildType (say, snapshot) also needs mapping and NDK symbols — but you don't want to spend the daily upload quota on that build. Since enable, offline, and ndk.enable are resolved separately for each build variant, override them for the specific buildType through hierarchical configuration (see Hierarchical configuration):
android {
buildTypes {
// Besides release, mapping and NDK symbols are also needed for the snapshot build
named("snapshot") {
appmetrica {
// By default enable=true only for release — enable it explicitly for snapshot,
// otherwise mapping will neither be collected nor uploaded
enable.set(true)
ndk {
// By default ndk.enable=false — enable it explicitly for snapshot,
// otherwise NDK symbols won't be collected
enable.set(true)
}
// To avoid spending the daily upload quota on snapshot, don't upload mapping
// and symbols automatically. They will still be collected locally in
// build/appmetrica/<variant>/result, and you can upload them manually later,
// see "Manual loading"
offline.set(true)
}
}
}
}
appmetrica {
// postApiKey is set once in the global block and applies to all variants,
// including snapshot above — no need to set it again in a per-buildType block
// (otherwise, with different values, you'll get "Conflicting values for postApiKey")
postApiKey.set("Post Api key")
}
Plugin parameters
Example configuration with all available parameters:
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
}
}
|
Parameter |
Description |
|
|
Post API key. If 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). |
|
|
Enables or disables the plugin for the given build variant. Doesn't affect collecting or uploading NDK symbols — that's controlled by the independent By default, Supports hierarchical configuration (see Hierarchical configuration). |
|
|
Enables the Affects the upload of both mapping and NDK symbols at the same time (regardless of whether Acceptable values:
The default value is Supports hierarchical configuration (see Hierarchical configuration). |
|
|
Path to the mapping file. The default value is the mapping file from the build (the Supports hierarchical configuration (see Hierarchical configuration). |
|
|
Lets plugin usage statistics be sent to AppMetrica. Acceptable values:
The default value is |
|
|
Behavior when two different AppMetrica libraries ( Acceptable values:
The default value is Supports hierarchical configuration (see Hierarchical configuration). |
|
|
This parameter is required to load symbols from the SO file to track native crashes. |
|
|
Enables or disables processing and uploading symbols from SO files. If enabled, symbol processing and upload tasks run automatically after the build. The default value is Supports hierarchical configuration (see Hierarchical configuration). |
|
|
SO files to process. By default, the plugin takes SO files from the 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). |
|
|
Additional SO files. Unlike Hierarchical configuration behavior: collections from all sources are merged. |
|
|
Automatically add the The default value is 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 isfalse. - Otherwise, if at least one source has the value
true— the result istrue. - 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 postApiKeyis logged, and the default value (an empty string) is used. Upload then won't happen — the plugin additionally emits the warningpostApiKey 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"))
}
}
}
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 ....
Manual loading
For manual upload, set 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.
-
In the app/build.gradle file, turn on
offlinemode:appmetrica { offline.set(true) }In
offlinemode, thepostApiKeyparameter is optional. -
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, ifndk.enableis enabled.
-
In the AppMetrica interface, go to the app settings from the menu on the left.
-
Go to the Crashes → Android tab.
-
Click Choose file and upload the desired archive.
Plugin tasks
For each build variant <variant> (Release, ProdRelease, etc.), the plugin registers the following tasks:
|
Task name |
Purpose |
|
|
Checks that exactly one AppMetrica library is used in the project (see |
|
|
Generates resources in |
|
|
Builds |
|
|
Uploads |
|
|
Converts SO files to |
|
|
Builds |
|
|
Uploads |
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
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 ofpostApiKey.- Dependency check error — Two AppMetrica libraries (
io.appmetrica.analytics:analyticsandcom.yandex.android:mobmetricalib) are found in the project at the same time. Remove one of them or, temporarily, setallowTwoAppMetricas = 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. SetpostApiKeyor enableoffline.Conflicting values for postApiKey: ...—postApiKeyis 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.