PDFs


This page applies to an earlier version of the AppDynamics App IQ Platform.
See the latest version of the documentation.


On this page:

Your Rating:
Results:
PatheticBadOKGoodOutstanding!
63 rates

Follow the steps below to manually instrument your Androids apps. You will need to download the Android Agent and manually inject dependencies.

Step 1: Download the Android SDK

  1. Navigate to the AppDynamics Download page.

  2. From the APP AGENT list, check the Mobile RUM Agent - Android check box.
  3. Click Download for the latest Android Agent that appears in the Releases results. This downloads a file named AndroidAgent-<version>.zip.

Step 2: Get Your Application Key

After you completed the Getting Started Wizard, you were given an EUM App Key. You will need this key when you modify the source code. In some cases, multiple mobile applications can share the same key.

If you have completed the Getting Started Wizard, but don't have your EUM App Key, see Get Your Application Key.

Step 3: 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.

Step 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.

The Android SDK does not support IBM Worklight or other frameworks that do not use the build.xml file defined in Android projects.

Add the AppDynamics Android Agent files

  1. Create a libs directory in your application root directory. This is often Application and a subdirectory of your project directory. Thus, this is where your libs directory might be located: ProjectName/Application/libs
  2. Copy ADEumAgent.jar to the libs directory.
  3. Copy ADEumInjector.jar to your application 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:

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:

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. Open a shell in the directory to which you downloaded and unzipped the SDK in step 1.
  2. Run the following commands to add the required artifacts to your local repository.

    mvn install:install-file -Dfile=adeum-maven-repo/com/appdynamics/appdynamics-maven-plugin/1.0/appdynamics-maven-plugin-1.0.jar -DpomFile=adeum-maven-repo/com/appdynamics/appdynamics-maven-plugin/1.0/appdynamics-maven-plugin-1.0.pom
    
    mvn install:install-file -Dfile=adeum-maven-repo/com/appdynamics/appdynamics-runtime/1.0/appdynamics-runtime-1.0.jar -DpomFile=adeum-maven-repo/com/appdynamics/appdynamics-runtime/1.0/appdynamics-runtime-1.0.pom
    
    mvn install:install-file -Dfile=adeum-maven-repo/com/appdynamics/appdynamics-injector/1.0/appdynamics-injector-1.0.jar -DpomFile=adeum-maven-repo/com/appdynamics/appdynamics-injector/1.0/appdynamics-injector-1.0.pom

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, Including Optional Automatic ProGuard File Uploading 

If your build system is Gradle-based you must:

  1. Add the AppDynamics Android Agent repository to your project.
  2. Modify your top-level build.gradle.
  3. Modify your module-level build.gradle.

Add the AppDynamics Android Agent repository to your project

Copy the adeum-maven-repo directory that you downloaded to both the directory where your top-level build.gradle file is and the directory where your module-level build.gradle is.

Modify your top-level build.gradle

Make the following changes to your top-level build.gradle:

  1. Edit or create the buildscript section and:
    1. Add adeum-maven-repo as a repository.

    2. Add the Android Tools plugin and the AppDynamics plugin versions you are using as classpath dependencies:

      1. For AppDynamics 3.9 and later, check to make sure that your Gradle version is compatible with your Android Tools plugin. Use com.appdynamics:appdynamics-gradle-plugin:2.0 for the AppDynamics plugin.

      2. For older versions of AppDynamics, use this table to confirm the compatibility of Gradle, Android Tools, and the AppDynamics plugin versions.

At this point, your top-level build.gradle should be similar to the following:

buildscript {
    repositories {
        jcenter()
        maven {url uri("adeum-maven-repo") } //this line added for AppDynamics
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.1.0'
         classpath 'com.appdynamics:appdynamics-gradle-plugin:4.+' //this line added for AppDynamics
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
 
allprojects {
    repositories {
        jcenter()
    }
}

Modify your module-level build.gradle

Make the following changes to your module-level build.gradle:

  1. Apply the adeum plugin immediately after the com.android.application plugin.
  2. Configure the adeum plugin to: 
    1. Section 1: Add your EUM account information so that you can automatically upload your ProGuard mapping files for crash reports with each build. This is the recommended way of managing ProGuard files, although manual modes are also possible. If you do not use ProGuard to obfuscate your files you can skip this step. If you are using the EUM Cloud (SaaS), Section 1 is all you need to do to automate uploading. You can also modify uploading behavior.
    2. Section 2: If you are using an EUM Server (on-prem) you also need to point the plugin to the collector of your on-prem instance.
    3. Section 3: Optional: exclude one or more class names from being instrumented, using the "adeum" excludeClasses snippet. Class names can contain wildcards:
      • '?' for a single character
      • +

At this point, your module-level build.gradle should look something like this.

apply plugin: 'com.android.application'
apply plugin: 'adeum'// this line added for AppDynamics

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.example.test.myapplication"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false 
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
 
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
}
 
adeum{   // configure the AppDynamics plugin
        
        // Section 1
        //add this information to allow the upload of ProGuard mapping files.  If you are using the EUM Cloud (SaaS), this automatically uploads your files with each build 
     
      account {
        name "The EUM Account Name from the License screen"
        licenseKey "The EUM License Key from the License screen"
        }
 
        //add this information if you want to modify upload behavior.
      proguardMappingFileUpload {
        failBuildOnUploadFailure true //should build fail if upload fails? Defaults to false
        enabled true //enables automatic uploads.  Defaults to true
        }
 
        // Section 2 - for an EUM Server (on premises)
        //add this information to point to the on-prem EUM Server
      url "https://example.com:7001"
 
        // Section 3 - optional.  To exclude named classes from instrumentation
      excludeClasses = ['android.support.multidex.*', 'okio.**']//Excludes all the classes in the android.support.multidex and okio packages.

}

Optional: Manually Inject AppDynamics Dependencies

In the set-up instructions above, the AppDynamics dependencies are automatically injected.  If automatic dependency injection is not working for your project, then you can use manual injection. To use manual injection, you first explicitly add the dependencies and then disable dependency injection.

Thus, the top-level build.gradle file would include the class path to the AppDynamics Gradle plugin as shown below:

buildscript {
    repositories {
        jcenter()
        maven {url uri("adeum-maven-repo") } //this line added for AppDynamics
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.1.0'
        classpath 'com.appdynamics:appdynamics-gradle-plugin:2.0' //this line added for AppDynamics
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}
 
allprojects {
    repositories {
        jcenter()
        maven {url uri("adeum-maven-repo") } //this line added for AppDynamics
    }
}

The module-level build.gradle also include the dependency and the configuration to disable injection as shown here:

apply plugin: 'com.android.application'
apply plugin: 'adeum'// this line added for AppDynamics

android {
    compileSdkVersion 21
    buildToolsVersion "21.1.2"

    defaultConfig {
        applicationId "com.example.test.myapplication"
        minSdkVersion 15
        targetSdkVersion 21
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false 
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
 
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:21.0.3'
    compile 'com.appdynamics:appdynamics-runtime:4.+' // manually add this line for AppDynamics
}
adeum {   
        // configure the AppDynamics plugin
        // section 1 - Disable injection of dependencies
      dependencyInjection {
        enabled = false // disables injection
        }
        // section 2
        //add this information to allow the upload of ProGuard mapping files.  If you are using the EUM Cloud (SaaS), this automatically uploads your files with each build 
      account {
        name "The EUM Account Name from the License screen"
        licenseKey "The EUM License Key from the License screen"
        }
 
        //add this information if you want to modify upload behavior.
      proguardMappingFileUpload {
        failBuildOnUploadFailure true //should build fail if upload fails? Defaults to false
        enabled true //enables automatic uploads.  Defaults to true
        }
 
        // section 3 - for an EUM Server (on-prem)
        //add this information to point to the on-prem EUM Server
      url "https://example.com:7001"
 
        // section 4 - optional.  To exclude named classes from instrumentation
      excludeClasses = ['android.support.multidex.*', 'okio.**']//Excludes all the classes in the android.support.multidex and okio packages.
}

Optional: Enable/Disable Instrumentation for Build Types

By default, instrumentation is enabled for both release and debug builds. In certain cases, however, you might want to disable instrumentation for a certain build. 

For example, if you are tracking down an issue in your code, you might want to disable instrumentation in the debug build and enable instrumentation in the release build. To do this, in the adeum object, set enabledForDebugBuilds to false and set enabledForReleaseBuilds to true as shown below.

...
adeum {
    //other stuff, if it exists
    // Optional. 
    // By default, instrumentation is enabled for both debug and release builds.
    // This controls instrumentation for "debuggable" build types.
      enabledForDebugBuilds   = false
    // This controls for non-debuggable build types. 
      enabledForReleaseBuilds = true
}
...

Verify the Instrumentation State at Runtime

If one or more of your builds has disabled instrumentation, you need to disable the instrumentation check at runtime. You can set boolean fields in the build configuration to disable the runtime verification of instrumentation. The runtime verification of instrumentation is on by default. You can turn it off using the method withCompileTimeInstrumentationCheck.

In the build configuration, you can set a boolean value for the CHECK_ENABLED field for build types. The table below shows the config value, the instrumentation state, and then describes the runtime behavior of your applications.

Config ValueInstrumentation StateRuntime Behavior
trueEnabledThe agent will verify that instrumentation has been enabled before initializing.
DisabledThe agent will verify that the instrumentation has not been enabled and then thowan IllegalState exception.
falseEnabledThe agent will initialize without checking whether instrumentation has been enabled.
Disabled

For example, in the build configuration below, the field CHECK_ENABLED is set to true for the release build and false for the debug build. The agent for the debug build will not verify if instrumentation has been enabled before executing instrumentation code, whereas, the application code for the release build will check before executing the instrumentation code.

...
android {
    // usual stuff
    buildTypes {
    // usual stuff
        release {//these lines added for AppDynamics
            //release based configuration
            // The release build by default is not "debuggable". 
            // The build config "CHECK_ENABLED" will be accessible in the runtime environment.
            // This enables the Android Agent to verify that the instrumentation has been enabled before running the initialization code.
            // If instrumentation has not been enabled, an "IllegalState" exception is thrown.  
            buildConfigField "boolean", "CHECK_ENABLED", "true"
        }
        debug {
            // Setting 'CHECKED_ENABLED' to "false" means the Android Agent will run the initaliazation code without confirming that
            // instrumentation has been enabled. No exception will be thrown.
            buildConfigField "boolean", "CHECK_ENABLED", "false"
        }
    }
}

...

If the value of CHECK_ENABLED is true, the Android Agent will confirm that instrumentation has been enabled before executing the initialization code. If the value is false, the Android Agent executes the initialization code regardless of whether instrumentation has been enabled.

The following instrumentation initialization code shows you how to check the value of the build config CHECK_ENABLED with the method withCompileTimeInstrumentationCheck.

import com.appdynamics.eumagent.runtime.Instrumentation;
...
Instrumentation.start(
        AgentConfiguration config = AgentConfiguration.builder()
            .withAppKey(<EUM_APP_KEY>)
            .withContext(this)
            .withCompileTimeInstrumentationCheck(BuildConfig.CHECK_ENABLED)
            .build();
);
...

Optional: Enable/Disable Native Crash Reporting

You can report native crashes caused by native libraries. See Configure Native Crash Reporting to learn how to enable native crash reporting and uploading the symbol file.

Step 5: Modify the source

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

    import com.appdynamics.eumagent.runtime.Instrumentation;
  2. In your primary Activity's onCreate() method, add the following lines, passing in the EUM App Key from step 2 above: 

    Instrumentation.start("<EUM_APP_KEY>", getApplicationContext());
  3. Save the file.

Your code should look something like this.

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

@Override
public void onCreate(Bundle savedInstanceState)
{
    ...
    Instrumentation.start("<EUM_APP_KEY>", getApplicationContext());
}

Optional: Configure the Android Agent for On-Prem Deployments

If you are using an on-prem EUM Server instead of the EUM Cloud, you need to tell the agent where to send its beacons and screenshot data. To do that, you create an AgentConfiguration object set the Collector URL and the Screenshot Service URL to your on-premises EUM Server URL. 

The Android Agent knows which path to use to make calls to different service (Collector/Screenshot Service). For example, if the EUM Server URL is https://myEUMServerURL.com:7001, the Android Agent will know to use https://myEUMServerURL.com:7001/eumcollector to make requests to the EUM Collector.

To get the EUM Server URL: 

  1. Open the Administration Console.
  2. From the left navigation bar, click Controller Settings.
  3. In the search field, enter eum.beacon.host or eum.beacon.https.host if you're using HTTPS.
  4. Copy the value for the configuration. This is your EUM Server URL.

In your primary Activity's onCreate() method, use the form below of the Instrumentation.start call. The value for $EUM_SERVER_URL should include the protocol, domain name, and port.

Instrumentation.start(AgentConfiguration.builder()
	.withContext(this)
 	.withAppKey("$EUM_APP_KEY")
	.withCollectorURL("$EUM_SERVER_URL")
    .withScreenshotURL("$EUM_SERVER_URL")
	.build());

Optional: Modify the source if you are using Gradle-based build types

If you are using a Gradle-based build and have added the "build types" instrumentation option in your module-level build.gradle file, you will need to do a little additional work. Instead of the above, in your primary Activity's onCreate() method, add the following lines:

Instrumentation.start(
        AgentConfiguration config = AgentConfiguration.builder()
            .withAppKey($CURRENT_APP_KEY")
            .withContext(this)
            .withCompileTimeInstrumentationCheck(BuildConfig.CHECK_ENABLED)
            .build();
);

Save the file.

Your code should then look something like this.

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

@Override
public void onCreate(Bundle savedInstanceState)
{
    ...
    Instrumentation.start(
        AgentConfiguration config = AgentConfiguration.builder()
            .withAppKey($EUM_APP_KEY")
            .withContext(this)
            .withCompileTimeInstrumentationCheck(BuildConfig.CHECK_ENABLED)
            .build();
);
}

Step 6: Rebuild the Application

Rebuild your application.  If you are using Gradle, use the -i flag (gradle -i).

In the console, you should see something like this:

 [injector] 				/=========================================\
 [injector] 				| AppDynamics BCI Instrumentation summary  |
 [injector] 				\=========================================/
 [injector]
 [injector]
 [injector] 		 - Total number of classes visited (#720 classes)
 [injector] 		 - Total number of classes instrumented (#1 classes)
 [injector] 		 - Total number of classes failed to instrument (#2 classes)
 [injector] 		 - Total number of features discovered (#3)
 [injector]

Verify your instrumentation - Ant

If you don't see this information printed in your console, either your project is incorrectly configured or the injector failed to run completely. There is a very detailed log of this process at <project>/bin/appdynamics_eum_android_bci.log

Verify your instrumentation - Maven

If you don't see this information printed in your console, either your project is incorrectly configured or the injector failed to run completely. There is a very detailed log of this process at <project>/target/appdynamics_eum_android_bci.log

Verify your instrumentation - Gradle

If you didn't use the -i flag, check to make sure there is a line in your console output that contains "inject". If you don't see this information printed in your console, either your project is incorrectly configured or the injector failed to run completely. There is a very detailed log of this process at <project>/build/appdynamics_eum_android_bci.log

Step 7: Manually Upload the ProGuard Mapping File (Optional)

You can skip this step if one of the following is true:

  • you did not obfuscate your application source code
  • you have set up automatic uploading of this file using Gradle and your build.gradle file (recommended)

To learn how to manually upload the mapping file, see Manually Upload the ProGuard Mapping File.

Step 8: 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 RUM. There are five basic kinds of extensions that you can create:

  • Custom timers: any arbitrary sequence of events within your code timed, even spanning multiple methods
  • Custom metrics: any integer-based data you wish to collect
  • User data: any string key/value pair you think might be useful
  • Information points: how often a single method is invoked, and how long it takes to run
  • Breadcrumbs: context for a crash

In addition, if you are using an environment with an on-premises EUM Server, you need to update your code to indicate the URL to which your agent should send its beacons. You can also set up the agent to use a custom HTTP library.

For more information, see Customize Your Instrumentation With the Android SDK.

Upgrade the Android Mobile Agent

As new features are added to the agent, you will need to upgrade the Android SDK in your app.

  1. Download the updated SDK as in step 1 above.
  2. Replace the .jar or repo files—depending on your build method—as in step 4 above, using the updated SDK.
  3. Rebuild your app.