How do I enable user experience monitoring for Android apps?

Follow the Android instructions below to instrument your Android app and benefit from user experience monitoring data. These instructions are easier to follow than the manual instrumentation process, which is offered as an alternative.

To begin instrumenting your app within your Android Studio project, or within your continuous integration build system, just integrate the generated Gradle fragment into your build.gradle file. This file contains a reference to the jcenter() maven repository so that the Gradle instrumentation plugin and classpath dependencies for the Dynatrace Gradle plugin will be fetched automatically.

The script line apply plugin: com.dynatrace.tools.android executes the instrumentation and receives the application-specific settings via the configuration section shown below.

The configuration parameters for applicationId and environmentId are automatically generated specifically for your mobile application, so don’t mix these values with the configuration scripts for your other mobile applications.

Once you’ve integrated the script within your own Gradle script, you can build and run your Android app to begin receiving monitoring data within Dynatrace.

Notes

  • If you’re using Android Studio 2.0, you’ll need to disable Instant Run. To do this, open the Settings or Preferences dialog. Navigate to Build, Execution, Deployment > Instant Run. Uncheck the box next to Enable Instant Run.
  • Dynatrace Android application monitoring is designed for Android API level 9+ applications.
  • If your app reaches the Multidex limit of more than 64K method declarations, please refer to the ‘Multi-dex applications’ section below.

Dynatrace Gradle plugin

The Dynatrace Gradle plugin is based on the Android Gradle plugin. It inserts an autoInstrument task into the Android build task sequence. This approach allows Android Studio users to modify their build.gradle file in a simple way and activate auto-instrumentation within few steps. The Dynatrace Gradle plugin is hosted on JCenter and Maven Central.

Supported Android Gradle plugin versions

{% table cols=”2” %}

{% cell header %} Dynatrace Gradle plugin {% endcell %}

{% cell header %} Required Android Gradle plugin version {% endcell %}

{% cell %} 7.0.0.2327 {% endcell %}

{% cell %} 1.5 - 2.3.2 {% endcell %}

{% endtable %}

Version 2.5 of the Android Plugin for Gradle will contain major changes and will break the current Dynatrace Gradle plugin version. Please check this page for further instructions before you upgrade to the 2.5 version. We will provide instructions once we’ve successfully adapted our plugin to the changes.

Configure your build script

To integrate the Dynatrace Gradle plugin into your build task sequence, you have to modify your module’s build.gradle file. First, you have to add the remote repository and the Dynatrace Gradle plugin dependency. Second, you have to add the dynatrace block with your configuration values.

buildscript {
  repositories {
    jcenter()
  }
  dependencies {
    classpath 'com.dynatrace.tools:android:+'
  }
}

apply plugin: 'com.dynatrace.tools.android'
dynatrace {
  defaultConfig {
    applicationId '<YourAppID>'
    environmentId '<YourEnvID>'
  }
}

The minimal configuration must contain the applicationId and the environmentId value. You can find these values on the settings page of your mobile application.

Additional OneAgent properties

To customize your auto-instrumentation process, you can use all auto-instrumentation properties. You have to specify these auto-instrumentation properties via the plugin property agentProperties. The syntax for this property is a key-value list, where the elements are separated by a comma and the key-value pair is separated by a colon.

dynatrace {
  defaultConfig {
    applicationId '<YourAppID>'
    environmentId '<YourEnvID>'
    agentProperties 'DTXInstrumentGPSLocation' : 'true', 'DTXLogLevel': 'debug'
  }
}

Dynatrace Managed

dynatrace {
  defaultConfig {
    applicationId '<YourAppID>'
    environmentId '<YourEnvID>'
    cluster '<your‐security‐gateway>'
    agentProperties 'DTXManagedCluster' : 'true'
  }
}

Use different product flavor configurations

If you use different product flavors, you can also specify different configurations for the auto-instrumentation task. For every product flavor the Gradle plugin will check to see if you’ve specified a configuration in the productFlavors block of the dynatrace block. If no configuration is available, the defaultConfig configuration will be used.

dynatrace {
  defaultConfig {
    applicationId '<YourAppID>'
    environmentId '<YourEnvID>'
  }

  productFlavors {
    prod {
      applicationId '<YourProdID>'
      environmentId '<YourEnvID>'
    }
  }
}

Combine with manual instrumentation

If you want to use a combination of manual and auto-instrumentation to monitor your app, then you should add the Dynatrace OneAgent library via the Dynatrace Gradle plugin. This allows you to automatically update the OneAgent library with the Gradle plugin and ensures that the OneAgent library and the auto-instrumentation have the same version. To enable the manual instrumentation, add the dependency dynatrace.agent(). This step is mandatory if you want to use the ‘identify user’ feature.

dependencies {
  compile dynatrace.agent()
}

For multi-dex applications you must ensure that all agent classes are in the primary dex file. We recommend to use the Android plugin property multiDexKeepProguard and add the line -keep class com.dynatrace.android.* { ; } to the provided file.

buildTypes {
  release {
    multiDexKeepProguard file('<your_keep_file>')
  }
}

OneAgent properties

###############################################################################
# Define your SSL settings if applicable. You may use any certificate or define
# your keystore and password. If SSL is used, be sure to specify https in the
# agentPath property above.
# bksFileName: the file name only ‐ no extension. For example, "mykeystore" in
# res/raw/mykeystore.bks

#DTXAllowAnyCert=true
#DTXBKSFileName=myKeyStore
#DTXBKSPassword=myPassword


###############################################################################
# Crash reporting settings. By default crash data reporting is enabled.

#DTXCrashReportingEnabled=false

#DTXInstrumentLifecycleMonitoring=false


###############################################################################
# By default all packages are instrumented for web request tagging and timing to provide
# visibility into 3rd party web requests. This property and DTXIncludePackages
# and DTXExcludePackages can be combined to fine tune the package instrumentation.
#
# For example, DTXIncludeAllPackages=true & DTXExcludePackages=a.b
# would include all packages but "a.b".
#
# DTXIncludeAllPackages=false & DTXIncludePackages=a.b would only include "a.b".

#DTXIncludeAllPackages=false

# Add other packages if desired ‐ use a comma as the separator.

#DTXIncludePackages=com.this.pkg,com.that.pkg

# Add packages, classes or methods to be excluded from instrumentation ‐ use a comma as
# the separator.

#DTXExcludePackages=com.xyz.IncludedClass.excludeThisMethod,com.xyz.ExcludedClass


###############################################################################
# Control whether to instrument for automatic user actions and how long before
# those actions stop accepting child events (web requests and user actions).
# By default, the instrumentation is on and the action time out is 500ms. The
# allowable values are between 100 ‐ 5000ms.

#DTXInstrumentAutoUserAction=false
#DTXAutoActionTimeoutMilliseconds=1000

# Set the maximum duration of an automatically created user action. After
# autoActionTimeoutMs expires, the action waits for any outstanding web requests
# or child actions up to this amount of time since the action is created. After
# this time, actions will be automatically closed. Valid range is 100ms‐540000ms.
# The default is 60000ms.

#DTXAutoActionMaxDurationMilliseconds=30000


###############################################################################
# Define other runtime options
# Logging level: "info" (default) or "debug". Note that the logging level is
# applied to both Auto Instrumentation as well as the instrumented application.

#DTXLogLevel=debug


###############################################################################
# Define the new version code and name for AndroidManifest.xml. The new version is
# required if Google Play is to be refreshed with the newly instrumented application.
# By default, Auto Instrumentation does change the version code and name. What's
# the difference between the version code and name? Read more here:
# http://developer.android.com/guide/topics/manifest/manifest‐element.html#vcode

#DTXVersionCode=1
#DTXVersionName=1.0


###############################################################################
# For KonyOne based applications, use the following property so that at runtime
# the key "serviceID" can be used to fetch its value, the operation name, which
# in turn is used as the wrapping action name.

#DTXNameUseValueOf=serviceID


###############################################################################
# Control whether to catch location updates from implementations of LocationListener
# When the onLocationChanged callback is triggered, the GPS location will be stored
# with a course precision (xx.yyy)
# Note: your application is responsible for requesting location permissions and
# implementing the listener.

#DTXInstrumentGPSLocation=true


###############################################################################
# Web request tagging is required (forced on) if web request timing is on.

#DTXInstrumentWebRequestTagging=false
#DTXInstrumentWebRequestTiming=false


###############################################################################
# For hybrid applications using the Javascript agent or Javascript bridge, cookies
# need to be set for each instrumented domain or server the app communicates with.
#
# Domain cookies are set with a preceding dot, i.e.: .company.com is used to
# set a cookie for every server on that domain.
#
# Subdomains are set the same way: .subdomain.company.com would set cookies for
# servers in that subdomain.
#
# Specific hosts are addressed directly: host.company.com
# IP addresses are handled directly, the same way as hosts: 192.168.0.1

#DTXSetCookiesForDomain=.domain.com, .subdomain.company.com, host.company.com, 192.168.0.1


###############################################################################
# For hybrid applications using file cookies (which are deactivated by default
# in Android) set this property to true, if you want to enable this support.

#DTXAllowFileCookies=true


###############################################################################
# MultiDex properties
#
# For multidex applications control the class moving process for the primary dex file

# Add packages or classes to the internal main dex list ‐ use a comma as the separator.
# Dependencies of the provided classes/packages are resolved and added to the
# internal main dex list
#DTXMultiDexKeep=com.example.\*, com.example2.Foo

# Add a list of classes from a file (use slashes or double backslashes) to the
# internal main dex list. The file must contain one class per line, in the
# following format: com/example/Foo.class
# It is possible to use the "maindexlist.txt" file from your Android Studio build.
#DTXMultiDexKeepFile=<path_to_project>/<project>/<module>/build/intermediates/multi‐dex/<build_variant>/maindexlist.txt

# Reduce the max amount of methods, that are stored in the primary dex file
# (the value must be smaller than 65536). Define a negative value to generate
# a primary dex file with the minimal number of methods (for testing purposes).
#DTXPrimaryDexLimit=60000

# Reduce the max amount of methods, that are stored in a secondary dex file
# (the value must be smaller than 65536).
#DTXSecondaryDexLimit=64000

ProGuard

If you use the identifyUser feature (or use a combination of manual and auto-instrumentation), then you have to exclude the Dynatrace agent library from optimization and obfuscation. You also have to exclude the okhttp3 package from obfuscation, when you want to monitor your OkHttp 3 web requests.

Add the following snippet to your ProGuard rule file:

keep class okhttp3.\*\* { \*; }
keep class com.dynatrace.android.\*\* { \*; }

Multi-dex applications

There is a limitation for the number of referenced methods in a given dex file. The specification limit for this number is 65,536. Android refers to that limit as the 64K reference limit. Android introduced the ART runtime with Android 5.0, which natively supports multidex applications. But for platforms prior to Android 5.0, Android uses the Davlik runtime, which only supports single-dex applications. With the multidex support library additional dex files can be used after the MultiDex.install() task was completed. Therefore all classes, that are loaded at the app start, have to be part of the primary dex file (classes.dex).

Because the auto-instrumentor inserts the agent start-up routine into the app start procedure, the agent code has to be part of the primary dex file. If there is not enough space in the primary dex file, then the auto-instrumentor will move some classes from the primary dex file into another dex file. For most apps the default settings should work. But for some apps you have to fine-tune the settings.

The auto-instrumentor analyzes your class dependencies based on the byte code of for app start procedure. If you hide your dependencies (f.e. with reflection), then the auto-instrumentor is not able to detect all your app start dependencies. If you use the Android gradle properties multiDexKeepFile and/or multiDexKeepProguard, then we recommend to add the specified classes also to the corresponding auto-instrumentor properties (or use the property DTXMultiDexKeepFile as descripted in the next section).

You should test the app start on a device with Android 4.4 or lower. If the app crashes with a java.lang.NoClassDefFoundError, then you have to add the missing class to the corresponding auto-instrumentation properties.

Fine-tune the multidex preparation step

You can use four properties to fine-tune the auto-instrumentation for mutlidex applications. With the properties DTXPrimaryDexLimit and DTXSecondaryDexLimit you can configure the limit of referenced methods for the primary and the secondary dex files. The properties DTXMultiDexKeep and DTXMultiDexKeepFile can be used to configure the internal main dex list of the auto-instrumentor.

The instrumentation step will increase the number of referenced methods (depending on your implementation) and will fail, if the number of referenced methods exceeds the 64K limit. The auto-instrumentor will also add the agent code into the primary dex file. For every dex file the number of referenced methods is analyzed and adapted before the instrumentation step. The auto-instrumentator adapts the number of referenced methods by moving a precalculated number of classes from the dex file to another dex file. With the properties DTXPrimaryDexLimit and DTXSecondaryDexLimit you can configure the final limit of referenced methods for this step. The property DTXPrimaryDexLimit sets the limit for the primary dex file (classes.dex) and the property DTXSecondaryDexLimit sets the limit for the secondary dex files (classes2.dex, classes3.dex, …).

Currently, the auto-instrumentor can’t calculate the number of added methods and therefore uses default values for the limits. The default value for DTXPrimaryDexLimit is around 62K and for DTXSecondaryDexLimit it is nearly 64K. This configuration should fit most applications and also keeps the changes to a minimum. If the auto-instrumentation fails for your application, then you have to update this two properties.

For the primary dex file the auto-instrumentor generates an internal main dex list and does not move this classes to another dex file. If you use the Android gradle plugin to build you apk file, then we recommend to use the property DTXMultiDexKeepFile. The Android gradle plugin generates a maindexlist.txt file. This file contains a list of classes, which have to be part of the primary dex file. You should specify this file via the property DTXMultiDexKeepFile.

DTXMultiDexKeepFile=<path_to_project>/<project>/<module>/build/intermediates/multi‐dex/<build_variant>/maindexlist.txt

You can also specify you own class list (in a file), that should be part of the primary dex file. Only one class per line is accepted, the class name has to end with the suffix .class and the package parts have to be separated with a slash (f.e. com/example/Foo.class). You can only specify one file for the property DTXMultiDexKeepFile. The auto-instrumentor does not analyze the dependecies of the specified classes. You have to track them manually.

If you do not want to track this dependencies manually, you can use the property DTXMultiDexKeep. The auto-instrumentor will automatically analyze the specified classes and will keep the classes with their dependencies in the primary dex file. You can specify a list of packages and classes (separated by a comma) with the property DTXMultiDexKeep.

DTXMultiDexKeep=com.example.\*, com.example2.Foo

This property is very useful when you receive a java.lang.NoClassDefFoundError on the app start-up for an Android 4.x device. You should add the classes (mentioned in the error message) to the property DTXMultiDexKeep and the auto-instrumentor will detect the dependencies of this class.

Build an ajusted apk file

If you want to reduce the execution time of the auto-instrumentor, you can also fine-tune the Android build process to generate an adjusted apk file. With this file you can skip the multidex preparation step from the auto-instrumentor. In this case you have to ensure that there is enough space for the mobile agent in the primary dex file. You can reach this goal with the --minimal-main-dex or --set-max-idx-number option from the dx command. You can set this option with the property additionalParameters from the Android gradle plugin .

--minimal-main-dex option: If you use this option, Android will only store classes in the primary dex file, that are needed for the app start procedure.

dexOptions {
        additionalParameters '‐‐minimal‐main‐dex'
}

--set-max-idx-number option: If you use this option, Android will reduce the referenced method limit to the specified value. This setting is used for all dex files of your apk.

dexOptions {
        additionalParameters '‐‐set‐max‐idx‐number=62000'
}

Before you modify your app settings, you should aware of the main dex list and how you can add missing classes to this main dex list.