본문으로 건너뛰기

Android 에이전트 적용

설치 전 요구사항

Android 에이전트를 설치하기 전에 다음 요구사항을 확인하세요.

  • Android Min Sdk 21 이상
  • 지원 환경: Android 5.0(API Level 21)+, Java 17+, Android Gradle Plugin 7.0 ~ 9.x, Gradle 7.0 ~ 8.x (AGP 9.x 사용 시 Gradle 8.x 필요)
노트

WhatapAgent Android SDK 2.3.0은 Android 애플리케이션의 성능 모니터링을 위한 SDK입니다. Gradle Plugin 2.2.2를 함께 적용하면 별도 코드 없이 자동 수집이 가능합니다.

에이전트 설치

Android에 와탭 모바일 에이전트를 설치하려면 다음 순서로 진행합니다.

  • 와탭 모바일 에이전트 설치 순서: Gradle 설정 → SDK 초기화 → Builder 옵션 → Manifest 설정 → ProGuard 설정 → 지원 수집 항목 → 수동 연동 → ScreenGroup 설정

1. Gradle 설정

에이전트를 설치하기 위해 프로젝트의 Gradle 파일을 수정해야 합니다. 프로젝트가 Kotlin DSL을 사용하는지 Groovy를 사용하는지에 따라 설정 방법이 다릅니다.

Kotlin DSL

Project 레벨 build.gradle.kts
plugins {
id("io.whatap.android") version "2.2.2" apply false
}
App 모듈 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 레벨 build.gradle
plugins {
id 'io.whatap.android' version '2.2.2' apply false
}
App 모듈 build.gradle
plugins {
id 'com.android.application'
id 'io.whatap.android'
}

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

2. 로컬 AAR 파일 방식 (폐쇄망 · 사내망)

배포받은 AAR 파일은 app/libs/에, 플러그인 JAR 파일은 필요 시 libs/ 또는 사내 Maven 저장소에 배치합니다. Plugin JAR을 사용하지 않는 경우에는 수동 연동 가이드의 API를 호출해 필요한 지점을 계측하세요.

Kotlin DSL (build.gradle.kts)

앱 모듈 build.gradle.kts
dependencies {
implementation(files("libs/whatap-android-agent-2.3.0.aar"))
}
선택 사항: 로컬 Plugin JAR
로컬 Plugin JAR (프로젝트 레벨 build.gradle.kts)
buildscript {
dependencies {
classpath(files("libs/whatap-android-plugin-2.2.2.jar"))
}
}

Groovy

앱 모듈 build.gradle
dependencies {
implementation files('libs/whatap-android-agent-2.3.0.aar')
}

3. SDK 초기화

Android 애플리케이션의 성능 데이터를 수집하기 위해 SDK를 초기화해야 합니다. Application 클래스에서 초기화하는 것을 권장합니다.

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 옵션

모든 Builder 옵션은 선택 사항이며, 지정하지 않으면 기본값이 적용됩니다.

전송 및 버퍼 옵션

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

수집 토글

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

HTTP 연결 옵션

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

ScreenGroup 및 사용자 옵션

  • setScreenGroupDelaySeconds(int): 0초
  • 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)
주의

사용량이 적은 시간대의 트래픽 줄이기: 백그라운드 상태에서도 heartbeat 및 리소스 샘플러가 전송될 수 있습니다. 필요하면 heartbeat 수집을 끄거나 flush 간격을 늘려 서버 요청 수를 줄일 수 있습니다.

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

5. Manifest 설정

AndroidManifest.xml 파일에 필요한 권한과 Application 클래스를 설정해야 합니다.

<?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 설정

# 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. 지원 수집 항목

  • Activity/Fragment 라이프사이클 및 ScreenGroup
  • 지원 네트워크 클라이언트의 요청·응답 정보
  • 리소스 사용량, 크래시 및 ANR
  • WebView 페이지 로드 및 성능 정보

8. 수동 연동

주의

setCollectNetwork(false)를 지정하면 네트워크 확장 모듈이 초기화되지 않아 wrap()onRequest() 호출이 동작하지 않습니다. 수동 네트워크 연동에는 기본값인 true를 유지하세요.

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는 자동 수집 대상이 아닙니다. Android 9(API 28) 이상에서 DefaultHttpClient와 HttpGet을 사용하려면 org.apache.http.legacy 사용 선언 또는 대체 의존성이 필요합니다. 이 선행 조건을 적용할 수 없으면 지원되는 네트워크 클라이언트를 사용하세요.

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 설정

위험

주요 변경: 기존 startGroup() / addTask() / endGroup() API가 startChain() / endChain()으로 교체되었습니다. 여러 Activity 또는 Fragment에 걸친 흐름은 startChain()으로 시작하고 종료 화면에서 동일 taskIdendChain()을 호출합니다. taskId를 생략하면 자동 생성되며 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)
}
}
}

체인 상태와 자동 종료 대기 시간: isChainActive()로 진행 중인 체인이 있는지 확인할 수 있습니다. 화면 사이에 짧은 공백이 있는 흐름은 종료 대기 시간을 늘려 하나의 그룹으로 유지하세요.

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

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

문제 해결 및 지원

문제 해결

Desugaring 관련 오류

Dependency 'io.whatap.android:whatap-android-agent:2.3.0' requires core library desugaring to be enabled for :app. 오류 발생 시 아래 설정을 추가합니다.

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 오류

Plugin을 찾을 수 없는 오류 발생 시 아래 설정을 추가합니다:

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

Java 버전 관련 오류

Java 버전 관련 오류 발생 시 아래 설정을 확인합니다:

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

Namespace 경고

Namespace 'io.whatap.android.agent' is used in multiple modules 경고는 무시해도 됩니다. 이는 라이브러리가 여러 모듈에서 사용되고 있음을 알리는 경고이며, 앱 실행에는 영향을 주지 않습니다.

빌드 오류 발생 시

  • Gradle 버전과 Android Gradle Plugin 버전이 요구사항을 충족하는지 확인하세요.
  • 네트워크 연결 상태를 확인하고 프록시 설정이 필요한 경우 설정하세요.
  • 프로젝트 Clean & Rebuild를 시도해 보세요.

데이터가 수집되지 않을 때

  • 프로젝트 액세스 키가 올바르게 설정되었는지 확인하세요.
  • 인터넷 권한이 AndroidManifest.xml에 추가되었는지 확인하세요.
  • Application 클래스에서 SDK 초기화가 제대로 되었는지 확인하세요.
  • 프록시나 방화벽 설정으로 인해 데이터 전송이 차단되지 않았는지 확인하세요.

지원

기술 지원 요청 시 다음 정보를 함께 제공하면 더 빠른 해결이 가능합니다.

  • 프로젝트 액세스 키
  • Android SDK 버전
  • Gradle 버전 및 Android Gradle Plugin 버전
  • 에러 로그 전문
  • build.gradle 파일 내용
  • 문제 재현 방법