Skip to main content

Apply Android Agent

Prerequisites

Before installing the Android agent, check the following requirements.

  • Android Min SDK 21 or higher
  • Supported environments: Android 5.0 (API Level 21)+, Java 17+, Android Gradle Plugin 7.0 ~ 9.x, Gradle 7.0 ~ 8.x (Gradle 8.x is required when using AGP 9.x)
Note

WhatapAgent Android SDK 2.3.0 is an SDK for monitoring the performance of Android applications. Applying the Gradle Plugin 2.2.2 together enables automatic collection without additional code.

Install Agent

To install the WhaTap mobile agent on Android, follow these steps.

  • WhaTap mobile agent installation order: Gradle settings → SDK initialization → Builder options → Manifest settings → ProGuard settings → Supported collection items → Manual instrumentation → ScreenGroup settings

1. Gradle Settings

To install the agent, you need to modify your project's Gradle files. The configuration differs depending on whether the project uses Kotlin DSL or Groovy.

Kotlin DSL

Project-level build.gradle.kts
plugins {
id("io.whatap.android") version "2.2.2" apply false
}
App module build.gradle.kts
plugins {
id("com.android.application")
id("io.whatap.android")
}

dependencies {
implementation("io.whatap.android:whatap-android-agent:2.3.0")
}

Groovy

Project-level build.gradle
plugins {
id 'io.whatap.android' version '2.2.2' apply false
}
App module build.gradle
plugins {
id 'com.android.application'
id 'io.whatap.android'
}

dependencies {
implementation 'io.whatap.android:whatap-android-agent:2.3.0'
}

2. Local AAR File (closed network / internal network)

Place the distributed AAR file under app/libs/, and place the plugin JAR file, if needed, under libs/ or your internal Maven repository. If you don't use the Plugin JAR, call the manual instrumentation API to instrument the points you need.

Kotlin DSL (build.gradle.kts)

App module build.gradle.kts
dependencies {
implementation(files("libs/whatap-android-agent-2.3.0.aar"))
}
Optional: Local Plugin JAR
Local Plugin JAR (project-level build.gradle.kts)
buildscript {
dependencies {
classpath(files("libs/whatap-android-plugin-2.2.2.jar"))
}
}

Groovy

App module build.gradle
dependencies {
implementation files('libs/whatap-android-agent-2.3.0.aar')
}

3. SDK Initialization

To collect performance data from the Android application, you need to initialize the SDK. We recommend initializing it in the Application class.

Kotlin

import android.app.Application
import io.whatap.android.agent.WhatapAgent

class MyApplication : Application() {
override fun onCreate() {
super.onCreate()
WhatapAgent.Builder.newBuilder()
.setProjectKey("<YOUR_PROJECT_ACCESS_KEY>")
.setServerUrl("<YOUR_SERVER_URL>")
.setPCode(<YOUR_PCODE>)
.build(this)
}
}

Java

import android.app.Application;
import io.whatap.android.agent.WhatapAgent;

public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
WhatapAgent.Builder.newBuilder()
.setProjectKey("<YOUR_PROJECT_ACCESS_KEY>")
.setServerUrl("<YOUR_SERVER_URL>")
.setPCode(<YOUR_PCODE>)
.build(this);
}
}

4. Builder Options

All Builder options are optional; if not specified, the default value is applied.

Transmission and buffer options

  • setFlushIntervalMs(long): 10,000 ms
  • setMaxDiskBytes(int): 500 × 1024
  • setMaxDiskFiles(int): 5
  • setQueueSize(int): 1,000

Collection toggles

  • setCollectScreenLoading(boolean): true
  • setCollectNetwork(boolean): true
  • setCollectHeartbeat(boolean): true

HTTP connection options

  • setKeepAliveEnabled(boolean): true
  • setMaxConnections(int): 5
  • setDisconnectAfterSend(boolean): false

ScreenGroup and user options

  • setScreenGroupDelaySeconds(int): 0 seconds
  • setExcludeLifecycleEventsFromScreenGroup(boolean): true
  • setUserId(String), setSessionId(String), setSampling(double)
WhatapAgent.Builder.newBuilder()
.setFlushIntervalMs(60_000L)
.setMaxDiskBytes(2 * 1024 * 1024)
.setMaxDiskFiles(5)
.setQueueSize(1000)
.setKeepAliveEnabled(true)
.setMaxConnections(5)
.setDisconnectAfterSend(false)
.build(this)
Caution

Reducing traffic during low-usage periods: Heartbeat and resource samplers can be sent even while the app is in the background. If needed, you can turn off heartbeat collection or increase the flush interval to reduce the number of requests to the server.

WhatapAgent.Builder.newBuilder()
.setCollectHeartbeat(false)
.setFlushIntervalMs(60_000L)
.build(this)

5. Manifest Settings

You must configure the required permissions and the Application class in the AndroidManifest.xml file.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<application
android:name=".MyApplication"
...>
</application>
</manifest>

6. ProGuard Settings

# Activity/Fragment
-keep class * extends android.app.Activity
-keep class * extends androidx.fragment.app.Fragment
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}

# WebView JavaScript Interface
-keepclassmembers class * {
@android.webkit.JavascriptInterface <methods>;
}

7. Supported Collection Items

  • Activity/Fragment lifecycle and ScreenGroup
  • Request/response information for supported network clients
  • Resource usage, crashes, and ANR
  • WebView page load and performance information

8. Manual Instrumentation

Caution

If you set setCollectNetwork(false), the network extension module is not initialized, so calls to wrap() and onRequest() will not work. Keep the default value of true for manual network instrumentation.

OkHttp3 / Retrofit

import io.whatap.android.agent.instrumentation.okhttp.OkHttp3Instrumentation

val client = OkHttpClient.Builder()
.connectTimeout(10, TimeUnit.SECONDS)
.build()

val instrumentedClient = OkHttp3Instrumentation.wrap(client)

val retrofit = Retrofit.Builder()
.baseUrl("https://api.example.com/")
.client(instrumentedClient)
.build()

Volley

import io.whatap.android.agent.instrumentation.volley.VolleyInstrumentation

val queue = Volley.newRequestQueue(this)
val request = StringRequest(Request.Method.GET, url, listener, errorListener)
queue.add(request)
VolleyInstrumentation.onRequest(request)

HttpURLConnection

import io.whatap.android.agent.instrumentation.httpurlconnection.HttpUrlConnectionInstrumentation

val raw = URL(urlString).openConnection() as HttpURLConnection
val connection = HttpUrlConnectionInstrumentation.wrap(raw)
connection.requestMethod = "GET"

Apache HttpClient

Apache HttpClient is not automatically collected. To use DefaultHttpClient and HttpGet on Android 9 (API 28) or higher, you need to declare the use of org.apache.http.legacy or add an alternative dependency. If you cannot apply this prerequisite, use a supported network client instead.

import io.whatap.android.agent.instrumentation.httpclient.ApacheHttpClientInstrumentation

val client = DefaultHttpClient()
val instrumentedClient = ApacheHttpClientInstrumentation.wrap(client)

val request = HttpGet(url)
val response = instrumentedClient.execute(request)

StackSpan

import io.whatap.android.agent.instrumentation.stacktrace.CallStackTracer

val span = CallStackTracer.start("LoginService", "doLogin")
try {
doLogin()
span.end()
} catch (error: Exception) {
span.endWithError(error)
throw error
}

9. ScreenGroup Settings

Danger

Key change: The existing startGroup() / addTask() / endGroup() API has been replaced with startChain() / endChain(). For a flow that spans multiple Activities or Fragments, start it with startChain(), then call endChain() with the same taskId on the ending screen. If you omit taskId, it is generated automatically and can be retrieved with getCurrentChainTaskId().

Kotlin

import android.content.Intent
import io.whatap.android.agent.instrumentation.screengroup.ChainView

private const val EXTRA_CHAIN_TASK_ID = "whatap_chain_task_id"

class LoginActivity : AppCompatActivity() {
private fun continueToConfirmation() {
ChainView.getInstance().startChain("LoginFlow", null)
val taskId = ChainView.getInstance().getCurrentChainTaskId() ?: return

startActivity(Intent(this, ConfirmationActivity::class.java)
.putExtra(EXTRA_CHAIN_TASK_ID, taskId))
}
}

class ConfirmationActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

intent.getStringExtra(EXTRA_CHAIN_TASK_ID)?.let { taskId ->
ChainView.getInstance().endChain(taskId)
}
}
}

Chain state and auto-end wait time: You can check whether a chain is in progress with isChainActive(). For flows with a short gap between screens, increase the end-wait time to keep them in a single group.

val isChainActive = ChainView.getInstance().isChainActive()

WhatapAgent.Builder.newBuilder()
.setScreenGroupDelaySeconds(3)
.build(this)

Troubleshooting & Support

Troubleshooting

If the error Dependency 'io.whatap.android:whatap-android-agent:2.3.0' requires core library desugaring to be enabled for :app. occurs, add the following configuration.

android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
isCoreLibraryDesugaringEnabled = true
}
}

dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.0")
}

Plugin not found error

If a plugin not found error occurs, add the following configuration:

pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}

Java version error

In case of Java version–related errors, check the following settings.

android {
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}

Namespace warning

The Namespace 'io.whatap.android.agent' is used in multiple modules warning can be ignored. It indicates the library is used in multiple modules and does not affect app execution.

Build errors

  • Verify that the Gradle version and Android Gradle Plugin version meet the requirements.
  • Check network connectivity and configure a proxy if necessary.
  • Try a Project Clean & Rebuild.

No data collected

  • Check if the project access key is set correctly.
  • Verify the internet permission is added in AndroidManifest.xml.
  • Ensure SDK initialization in the Application class.
  • Check for proxy/firewall settings blocking data transfer.

Support

When requesting technical support, providing the following information can lead to a faster resolution.

  • Project access key
  • Android SDK version
  • Gradle version and Android Gradle Plugin version
  • Full error log
  • build.gradle file contents
  • Steps to reproduce the issue