AppDynamics Application Intelligence Platform

3.9.x Documentation

PDFs

Learn by Watching

Doc Maps

Skip to end of metadata
Go to start of metadata

Watch a quick overview of the main steps of the process.
 

Direct link: https://appdynamo.wistia.com/medias/gq6toglcej.

1. Access the instrumentation window

  1. In the left navigation bar, select the application that you have enabled.
    This is either the server-side instrumented application that your mobile application communicates with or an application that you have created manually. 
  2. On the left nav bar,  click Configure -> Instrumentation.
  3. Click the End User Experience tab.
  4. Click the Mobile Apps subtab.

2. Download the Android SDK

Click the Android SDK link in step .  This downloads a file named AndroidAgent.zip.  This file unzips to a folder named Android Agent, which contains the files and folders discussed in Set Up Your Environment.

You must download the SDK separately for each application that you instrument.

3. Record the Application Key

Record the application key generated for this application, displayed in step .

You will need this key when you modify the source code.

4. Set Up Your Environment

Follow these instructions based on your build environment:

If you use Eclipse ADT to produce your builds, first build the application with ant and then follow the instructions for the Android Ant installation.

Setup for Ant

If your build system is ant-based you must:

  1. Add agent files to the project
  2. Add a post-compile target

Add the AppDynamics Android agent files

  1. Copy ADEumAgent.jar to the libs subdirectory in your project.
  2. Copy ADEumInjector.jar to your project's root directory.

Add a post-compile target

Do one of the following:

-- If there is no custom_rules.xml file in your project:

  1. Create a file in your project's root directory named custom_rules.xml.
  2. Copy and paste the following text into that file.
<project>
    <target name="-post-compile">
        <taskdef name="injector"
                 classname="com.appdynamics.android.ant.EUMAgentInjectorTask"
                 classpath="ADEUMInjector.jar"/>
        <injector classfilespath="${out.classes.absolute.dir}"
                  outputlocation="${out.absolute.dir}/instrumented-jars/"
                  instrumentationjarlocation="${jar.libs.absolute.dir}/ADEUMAgent.jar"
                  jarfilesrefid="project.all.jars.path"
                  androidjarlocation="${project.target.android.jar}"/>
    </target>
</project>

-- If there is an existing custom_rules.xml file in your project but it does not contain a "-post-compile" target:

  1. Add the following text to the end of the existing <project> element:
<target name="-post-compile">
    <taskdef name="injector"
             classname="com.appdynamics.android.ant.EUMAgentInjectorTask"
             classpath="ADEUMInjector.jar"/>
    <injector classfilespath="${out.classes.absolute.dir}"
              outputlocation="${out.absolute.dir}/instrumented-jars/"
              instrumentationjarlocation="${jar.libs.absolute.dir}/ADEUMAgent.jar"
              jarfilesrefid="project.all.jars.path"
              androidjarlocation="${project.target.android.jar}"/>
</target>

-- If there is an existing custom_rules.xml file in your project and it already contains a "-post-compile" target:

  1. Add the following text to the end of the existing "-post-compile" <target> element:
<taskdef name="injector"
             classname="com.appdynamics.android.ant.EUMAgentInjectorTask"
             classpath="ADEUMInjector.jar"/>
    <injector classfilespath="${out.classes.absolute.dir}"
              outputlocation="${out.absolute.dir}/instrumented-jars/"
              instrumentationjarlocation="${jar.libs.absolute.dir}/ADEUMAgent.jar"
              jarfilesrefid="project.all.jars.path"
              androidjarlocation="${project.target.android.jar}"/>

If you are using Eclipse + Ant

Do not include android.jar in the list of jar files provided as "jarfilesrefid" to your injector task.

For example if your build.xml looks something like this:

<taskdef name="injector"
	classname="com.appdynamics.android.ant.EUMAgentInjectorTask"
	classpath="ADEUMInjector.jar"/>
<injector classfilespath="${out.classes.absolute.dir}"
	outputlocation="${out.absolute.dir}/instrumented-jars/"
	instrumentationjarlocation="${jar.libs.absolute.dir}/ADEUMAgent.jar"
	jarfilesrefid="project.all.jars.path"
	androidjarlocation="${project.target.android.jar}"/>

Make sure that android.jar is not included in the list of files specified by the refid "project.all.jars.path". Otherwise the injector will fail to instrument your build properly.

Setup for Maven

If your build system is maven you must:

  1. Add the agent repository
  2. Add the maven runtime dependency
  3. Add the maven plugin

These instructions assume you are building your application using the android-maven-plugin with Maven 3.1.1+.

Add the AppDynamics Android agent repository to your project

  1. Copy the adeum-maven-repo directory that you downloaded to your project directory. This is the directory that contains pom.xml.
  2. Add the following code to the <repositories> section of your pom file:
<repositories>
    <repository>
        <id>adeum</id>
        <name>AppDynamics Repo</name>
        <url>file://${project.basedir}/adeum-maven-repo</url>
    </repository>
</repositories>

Add the maven runtime dependency

Add the following code to the <dependencies> section:

<dependency>
     <groupId>com.appdynamics</groupId>
     <artifactId>appdynamics-runtime</artifactId>
     <version>1.0</version>
 </dependency>

Add the maven plugin

Add the following code to the <plugins> section:

<plugin>
    <groupId>com.appdynamics</groupId>
    <artifactId>appdynamics-maven-plugin</artifactId>
    <version>1.0</version>
    <executions>
        <execution>
            <phase>compile</phase>
            <goals>
                <goal>adinject</goal>
            </goals>
        </execution>
    </executions>
</plugin>

Setup for Gradle

If your build system is gradle-based you must:

  1. Add the AppDynamics Android agent repository to your project
  2. Modify your build.gradle

Add the AppDynamics Android agent repository to your project

Copy the adeum-maven-repo directory that you downloaded to your project directory. This is the directory that contains your build.gradle file.

Modify build.gradle

Make the following changes to build.gradle:

  1. Edit or create the "buildscript" section and:

    1. Force dependency on the version of the Android plugin used to build your APK files, for example 'com.android.tools.build:gradle:0.8.3'

    2. Add "adeum-maven-repo" as a repository

    3. Add the version of the Android plugin you are using as a classpath dependency

    4. Add the appropriate version of the AppDynamics plugin as a classpath dependency.  See the table to determine the correct version.

      AppDynamics versionGradle versionAndroid Tools plugin versionAppDynamics plugin version
      3.8.0 and later1.80.6.3

      com.appdynamics:appdynamics-gradle-plugin:1.0

      N/A1.90.7.0, 0.7.1,0.7.3,0.8.3, 0.9.2These Android Tools versions do not support this version of Gradle
      3.8.3 and later1.100.7.3,0.8.3, 0.9.2com.appdynamics:appdynamics-gradle-plugin:2.0
      3.9 and later1.100.7.3,0.8.3, 0.9.2, 0.10x, 0.11x, 0.12xcom.appdynamics:appdynamics-gradle-plugin:2.0
      3.9 and later1.120.10x, 0.11x, 0.12xcom.appdynamics:appdynamics-gradle-plugin:2.0 
      3.9 and later2.10.13.0com.appdynamics:appdynamics-gradle-plugin:2.0 
  2. In the main section:
    1. Apply the "adeum" plugin immediately after the "android" plugin.
    2. Add "adeum-maven-repo" as a repository.

    3. Add "com.appdynamics:appdynamics-runtime:1.0" as a compile-time dependency. 

After you have added all the AppDynamics Android Agent requirements, your build.gradle resembles this:

buildscript {
	configurations.classpath.resolutionStrategy.force('com.android.tools.build:gradle:0.8.3')
	repositories {
		maven {url uri("adeum-maven-repo") }
		//mavenCentral() or whatever repo definitions you are using
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.8.3', 'com.appdynamics:appdynamics-gradle-plugin:2.0'
    }
}
 
apply plugin: 'android'
apply plugin: 'adeum'
 
repositories {
    maven {
        url uri('adeum-maven-repo')
    }
}
 
dependencies {
    compile 'com.appdynamics:appdynamics-runtime:1.0'
}  

5. Integrate ProGuard, if Necessary

If you use ProGuard to verify or optimize your code, add the following lines to your Proguard configuration file, by default proguard.cfg.

(info) Depending on your environment, this file may renamed by your build.

-keep class com.appdynamics.eumagent.runtime.DontObfuscate
-keep @com.appdynamics.eumagent.runtime.DontObfuscate class * { *; }

If you use Proguard to obfuscate your code, note the name and location of the mapping file that ProGuard produces, because AppDynamics needs this file to create human-readable stack traces for crash snapshots. For details about why you should do this, see Get Human-Readable Crash SnapshotsFor more information on the process, see Uploading the ProGuard Mapping File.

Every time the application is changed and recompiled the ProGuard mapping file changes, so you need to upload the new mapping file to AppDynamics every time you modify your app.

6. Modify Your Application Source Code

Modify the source code to initialize the mobile agent as soon as the app launches. A good place to do this is the onCreate() method of your application's primary Activity. This registers your application, and only needs to be done once in your code.

Modify the source

In the source file that defines your application's primary Activity, add the following import:

import com.appdynamics.eumagent.runtime.Instrumentation;

 In your primary Activity's onCreate() method, add the following line:

Instrumentation.start("$CURRENT_APP_KEY", getApplicationContext());

Save the file.

Your code should look something like this.

import com.appdynamics.eumagent.runtime.Instrumentation;
...

@Override
public void onCreate(Bundle savedInstanceState)
{
    ...
    Instrumentation.start($CURRENT_APP_KEY", getApplicationContext());
}

7. Add the Required Permissions

Open your application's AndroidManifest.xml file and verify that it has these permissions:

<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>

If both of these permissions are not present, add them.

8. Rebuild the Application

Rebuild your application.

Verify your instrumentation - Ant

After your build has run, make sure that the post-compile target has completed by checking the build output.   Some of the lines in the post-compile section output should be prefixed with [injector], for example:

-post-compile:
 [injector] Path to class files: /Users/username/android/networklogger/bin/classes
 [injector] Path to instrumentation jar: /Users/username/android/networklogger/libs/ADEUMAgent.jar
 [injector] Path to Android jar: /Users/username/android-2/platforms/android-18/android.jar
 [injector] Copying /Users/username/android/networklogger/libs/ADEUMAgent.jar to /Users/username/android/networklogger/bin/instrumented-jars/d5672e56-062a-479b-ba88-88b367319497.jar

If the target does not run successfully, your app will not be properly instrumented.

Verify your instrumentation - Maven

After your build has run, make sure your application has been instrumented.   Check the console output of your build and make sure there is a line that contains "Injecting:"

Verify your instrumentation - Gradle

After your build has run, make sure your application has been instrumented.   Check the console output of your build and make sure there is a line that contains "Inject:"

9. Upload the ProGuard Mapping File

(info) If you did not obfuscate your application source code, you can skip this step.

This step is optional but highly recommended if you obfuscated your code and plan to monitor crashes. AppDynamics needs the mapping file for the application to produce human-readable stack traces for crash snapshots. By default, the mapping file is named mapping.txt, unless you have renamed it in your build.

(warning) If you update your application, you need to upload the new version of the mapping file.

To associate the mapping file with the correct version of the application, you need to provide:

  • the package name of the Android package for the application
  • the version code for that application from the AndroidManifest.xml file

You can either upload the mapping file using the instrumentation screen in the Controller UI or use a special REST API. Perform the upload separately for each ProGuard mapping file that you are providing.

Upload the ProGuard Mapping File using the UI

  1.  In the instrumentation window in the controller UI, click the Upload ProGuard mapping file for Android crashes button.
  2. In the ProGuard mapping file upload window, either 
    • select an existing package from the dropdown list
      or 
    • enter a new package name for the mobile application.

(info) If the application is already registered with the controller, you can select its package which is listed in the dropdown list.
If the application is not yet registered, enter the package name in the New Package field.

  1. Enter the version code (a number) for the package. This is the versionCode  property in the AndroidManifest.xml of the application for which this mapping file was generated.
  2. Click Select ProGuard mapping file.
    The uploader expects a file with .txt extension. The file is named mapping.txt.
  3. In the file browser locate and select the mapping file and click Open.
  4. Click Upload.

Upload the ProGuard Mapping File using the API

The api uses HTTP basic authentication to send a PUT request to AppDynamics. The username is your AppDynamics account name and the password is your EUM license key.

1. Set up your HTTP basic authentication credentials

  1. In the upper right section of the Controller UI, click Settings -> License.
  2. Scroll down to the End User Experience Management panel.
  3. Note the Account Name at the top of the panel. This is your username for authentication.
  4. Note the License Key just below the Account Name. This is your password for authentication.

  5. URL-encode the account name and the license key.
  6. Generate an authentication string of the form: "<URL-encoded EUEM account name>:<URL-encoded EUEM license key>" and base64 encode it. You will use this string the following step.
  7. Add an authentication header to each request, setting its value to "Basic <authentication string>"

2. Send the mapping file

Send the ProGuard mapping file as as a text file in the body of the PUT request to the following URI:

https://api.eum-appdynamics.com/eumaggregator/crash-reports/proguardMappingFile/<androidPackageName>/<versionString>

These parameters are required:

  • androidPackagename: the name of the Android package for which this mapping file was generated
  • versionString: the string representation of the "versionCod"e property in the AndroidManifest.xml of the application for which this mapping file was generated

The request body contains the mapping file. The content type of the body is either text/plan or gzip if the body was ended with gzip.

Sample Request and Response Using the REST API

This is a sample request and response using the REST API.

Upload Request

The following example uses curl to send a mapping file. The account name is "Example account" and the license key/password is "Example-License-Key-4e8ec2ae6cfe". The plus signs replace spaces in the account name when the account name is URL-encoded. The package name for the Android application is "com.example.networklogger". The mapping file corresponds to the version with versionCode 1.

curl -v --upload-file mapping.txt --user Example+account:Example-License-Key-4e8ec2ae6cfe https://api.eum-appdynamics.com/eumaggregator/crash-reports/proguardMappingFile/com.example.networklogger/1

Upload Response

The successful output of the example request looks like this:

* About to connect() to api.eum-appdynamics.com port 443 (#0)
*   Trying ::1...
* connected
* Connected to api.eum-appdynamics.com  (::1) port 443 (#0)
* Server auth using Basic with user 'Example+account'
> PUT /eumaggregator/crash-reports/proguardMappingFile/com.example.networklogger/1 HTTP/1.1
> Authorization: Basic SW50ZXJuYWwrdGVzdCthY2NvdW50OlRlc3RBY2N0LTFlMzktNDVkMy05MzAzLTRlOGVjMmFlNmNmZQ==
> User-Agent: curl/7.24.0 (x86_64-apple-darwin12.0) libcurl/7.24.0 OpenSSL/0.9.8y zlib/1.2.5
> Host: app.eum-appdynamics.com
> Accept: */*
> Content-Length: 4
> Expect: 100-continue
>
< HTTP/1.1 100 Continue
* We are completely uploaded and fine
< HTTP/1.1 200 OK
< Content-Length: 0
< Server: Jetty(8.1.4.v20120524)
<
* Connection #0 to host app.eum-appdynamics.com left intact
* Closing connection #0

10. Customize Your Instrumentation (Optional)

The Instrumentation class has additional methods to allow you to extend the kinds of application data you can collect and aggregate using Mobile EUEM.  There are three basic kinds of extensions that you can create:

  • custom timers
  • custom metrics
  • information points

In addition, if you are using an environment with an on-premise version of the EUEM Processor, you need to update your code to indicate the URL to which your agent should send its beacons.

For more information, see Customize Your Android Mobile Instrumentation.