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.

Gradle examples

Additional OneAgent properties

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'
  }
}

Multiple product flavors

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

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

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. See
# Dynatrace.enableCrashReporting(boolean sendCrashData)

#DTXCrashReportingEnabled=false
#DTXSendCrashReports=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

###############################################################################
# Define 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

###############################################################################
# For hybrid applications using OneAgent for JavaScript 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. For example, `.company.com` can be used to
# set a cookie for every server in the domain `company.com`.
#
# Subdomains are set the same way. For example, `.subdomain.company.com` would set cookies for
# all servers in the `subdomain.company.com` subdomain.
#
# Specific hosts are addressed directly. For example, `host.company.com`
# IP addresses are handled directly, the same way as hosts. For example, `192.168.0.1`

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

ProGuard

For the retrofit2 web request instrumentation, you have to keep the retrofit2/okhttp3 classes. Add the following snippet to your ProGuard rule file:

-keep class okhttp3.** { *; }
-keep class retrofit2.** { *; }

Multi-dex applications

There is a Dalvik limitation for the number of methods in a given DEX file (https://developer.android.com/studio/build/multidex.html). The auto-instrumentation process will fail if the number of methods from the DEX file plus those from OneAgent for Android exceeds this method limit. If the application is a multi-dex application, the auto-instrumentor will attempt to move some methods from the full DEX file to another DEX file. With the 6.5 version, the auto-instrumentor tries different settings to find a suitable value for the number of moved methods.

You can also manually control this workflow using the following properties:

DTXMaxDexMethods=65000
DTXMultidexMoveMethodCount=X

Where X depends on your application and may be different for each release. When you use this option, you should read the log lines carefully. There are important messages you should consider:

  • “New primary DEX file is still too large”: You have to increase the DTXMultidexMoveMethodCount, because the free space in the DEX file is too low.
  • “DTXMultidexMoveMethodCount = X but should be <= Y (and DTXMaxDexMethods=65000) to avoid runtime errors on Android earlier than 5.0”: This messages shows the max value Y for the property DTXMultidexMoveMethodCount.

If you use the DTXMultidexMoveMethodCount option, you should test the app start on a device with Android 4.4 or lower. If the app crashes with a java.lang.NoClassDefFoundError, the auto-instrumentor has removed a mandatory class from the main DEX file. In this case you have ignored the warning from the auto-instrumentor and you must use a smaller DTXMultidexMoveMethodCount value. In this case the auto-instrumentor won’t cancel the instrumentation and will generate a valid APK for Android 5.0 and higher.

If the max DTXMultidexMoveMethodCount is still too small, then a mandatory class in the dex file can’t be moved. In this case you have to build a new APK file that contains enough space for OneAgent for Android. The DEX files can be built with the --minimal-main-dex or --set-max-idx-number option. For Android Studio we recommend that you use the Android Gradle plugin version 2.2.0 (or higher) and that you use the additional parameter property (http://google.github.io/android-gradle-dsl/2.2/com.android.build.gradle.internal.dsl.DexOptions.html#com.android.build.gradle.internal.dsl.DexOptions:additionalParameters).

--minimal-main-dex option: Only mandatory classes for the app start are stored in the main DEX file

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

--set-max-idx-number option: You can reserve some space in the DEX files for OneAgent for Android.

dexOptions {
        additionalParameters '--set-max-idx-number=64000'
}