dt-setup-android

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Android Dynatrace Instrumentation

Android Dynatrace 监控插装指南

Scope: Basic setup only — from zero to first event. For anything beyond initial instrumentation (custom actions, crash grouping, data privacy policies, etc.) refer to the Dynatrace documentation directly.
适用范围: 仅基础设置——从0到首次事件。若涉及初始插装之外的内容(自定义操作、崩溃分组、数据隐私政策等),请直接参考Dynatrace官方文档。

Phase 1: Preflight

阶段1:前置检查

Before doing anything else, check that the current directory is an Android project root by looking for
settings.gradle.kts
or
settings.gradle
. If neither exists, stop and tell the user this is not an Android project root, and ask them to navigate to the correct directory.
Then verify the following minimum requirements. If any are not met, stop and inform the user of what needs to be upgraded before proceeding:
RequirementMinimum
Gradle7.0.2
Android Gradle Plugin (AGP)7.0
JVMJava 11
Run
./gradlew --version
(or
gradlew.bat --version
on Windows). The output covers both Gradle and the actual JVM Gradle is using (the
Daemon JVM
line), which may differ from the system Java when the project is opened in Android Studio or IntelliJ. Do not use
java -version
— it may report a different JDK than what the build actually runs on. The AGP version is declared in the root build file.
在进行任何操作前,通过查找
settings.gradle.kts
settings.gradle
文件确认当前目录为Android项目根目录。若两者均不存在,立即停止操作并告知用户当前并非Android项目根目录,请用户导航至正确目录。
随后验证以下最低要求。若任何一项未满足,立即停止操作并告知用户需要升级的内容:
要求最低版本
Gradle7.0.2
Android Gradle插件(AGP)7.0
JVMJava 11
运行
./gradlew --version
(Windows系统运行
gradlew.bat --version
)。输出内容包含Gradle版本以及Gradle实际使用的JVM版本(
Daemon JVM
行),该版本可能与Android Studio或IntelliJ中打开项目时使用的系统Java版本不同。请勿使用
java -version
命令——它可能与构建实际运行的JDK版本不符。AGP版本在根构建文件中声明。

Phase 2: Detect existing setup

阶段2:检测现有配置

If a
dynatrace { }
block or a
configure<com.dynatrace.tools.android.dsl.DynatraceExtension> { }
block (also written as
configure<DynatraceExtension> { }
when the class is imported) is found anywhere in the build files, read it and extract if present:
  • applicationId
    (the value passed to
    applicationId(...)
    or
    applicationId '...'
    )
  • beaconUrl
    (the value passed to
    beaconUrl(...)
    or
    beaconUrl '...'
    )
Save these as pre-filled values to carry into Phase 3. If either value is absent or uses a placeholder (e.g.
YOUR_APPLICATION_ID
), treat it as not found. Proceed to Phase 3.
若在构建文件中发现
dynatrace { }
代码块或
configure<com.dynatrace.tools.android.dsl.DynatraceExtension> { }
代码块(当类已导入时也可写为
configure<DynatraceExtension> { }
),读取并提取以下内容(若存在):
  • applicationId
    (传递给
    applicationId(...)
    applicationId '...'
    的值)
  • beaconUrl
    (传递给
    beaconUrl(...)
    beaconUrl '...'
    的值)
将这些值保存为预填充值,带入阶段3。若任一值缺失或使用占位符(如
YOUR_APPLICATION_ID
),则视为未找到。继续执行阶段3。

Phase 3: Collect inputs

阶段3:收集配置信息

First, ask only for:
  1. applicationId
    — Dynatrace application ID. Tell the user this can be found in their Dynatrace tenant, inside the mobile application they have already created. If a value was extracted in Phase 2, show it as the current value and ask the user to confirm or replace it.
  2. beaconUrl
    — Dynatrace beacon URL. Tell the user this can also be found in their Dynatrace tenant, inside the same mobile application configuration. Same: show the extracted value if available and ask to confirm or replace.
Once the user confirms or provides both, then ask — unless the user already stated their session replay preference in their initial request, in which case skip this question and use what they said:
  1. Session replay — should session replay be enabled? (yes/no)
首先,仅询问以下两项:
  1. applicationId
    ——Dynatrace应用ID。告知用户该ID可在其Dynatrace租户中已创建的移动应用内找到。若阶段2中提取到值,显示该值并请用户确认或替换。
  2. beaconUrl
    ——Dynatrace beacon URL。告知用户该URL同样可在Dynatrace租户的同一移动应用配置中找到。同样:若有提取值则显示并请用户确认或替换。
用户确认或提供上述两项后,接下来询问——除非用户在初始请求中已说明会话重放偏好,否则跳过此问题并使用用户已提供的选项:
  1. 会话重放——是否启用会话重放?(是/否)

Phase 4: Locate files

阶段4:定位文件

Finding the app module

查找应用模块

The application module is not always named
app
. Read
settings.gradle.kts
or
settings.gradle
to find all included modules, then check each module's build file for the
com.android.application
plugin. Use the directory of the first module that applies it as
APP_MODULE
for all paths below.
macOS / Linux:
bash
grep -r -l --include="*.gradle" --include="*.gradle.kts" --exclude-dir=buildSrc "com.android.application" .
Windows (cmd):
text
findstr /s /m "com.android.application" *.gradle *.gradle.kts
Windows (PowerShell):
text
Get-ChildItem -Recurse -Include "*.gradle","*.gradle.kts" | Select-String "com.android.application" | Select-Object -ExpandProperty Path
Discard any result where the matching line contains
apply false
— those are version-catalog declarations in the root build file, not actual plugin applications. Also discard any result under
buildSrc/
.
If no module applying
com.android.application
is found after filtering, stop and report the failure — no files have been modified at this point.
应用模块并非始终命名为
app
。读取
settings.gradle.kts
settings.gradle
文件找到所有包含的模块,然后检查每个模块的构建文件是否应用
com.android.application
插件。将第一个应用该插件的模块目录作为后续所有路径的
APP_MODULE
macOS / Linux:
bash
grep -r -l --include="*.gradle" --include="*.gradle.kts" --exclude-dir=buildSrc "com.android.application" .
Windows (cmd):
text
findstr /s /m "com.android.application" *.gradle *.gradle.kts
Windows (PowerShell):
text
Get-ChildItem -Recurse -Include "*.gradle","*.gradle.kts" | Select-String "com.android.application" | Select-Object -ExpandProperty Path
丢弃所有匹配行包含
apply false
的结果——这些是根构建文件中的版本目录声明,并非实际插件应用。同时丢弃
buildSrc/
目录下的结果。
若过滤后未找到应用
com.android.application
的模块,立即停止操作并报告失败——此时尚未修改任何文件。

Files to read before editing

编辑前需读取的文件

  • Root
    build.gradle.kts
    /
    build.gradle
    (sibling of the settings file)
  • App
    APP_MODULE/build.gradle.kts
    /
    APP_MODULE/build.gradle
  • Entry-point source file — see below
  • 根目录
    build.gradle.kts
    /
    build.gradle
    (与settings文件同级)
  • 应用模块
    APP_MODULE/build.gradle.kts
    /
    APP_MODULE/build.gradle
  • 入口源文件——见下文

Finding the entry-point file

查找入口文件

Preferred: Application class. Search the source tree for a class that extends
Application
using the appropriate command for the OS:
macOS / Linux:
bash
grep -r -l --include="*.java" "extends Application" APP_MODULE/src
grep -r -l --include="*.kt" ": Application()" APP_MODULE/src
Windows (cmd):
text
findstr /s /m "extends Application" APP_MODULE\src\*.java
findstr /s /m ": Application()" APP_MODULE\src\*.kt
Windows (PowerShell):
text
Get-ChildItem -Recurse -Path APP_MODULE/src -Include "*.java" | Select-String "extends Application" | Select-Object -ExpandProperty Path
Get-ChildItem -Recurse -Path APP_MODULE/src -Include "*.kt" | Select-String ": Application()" | Select-Object -ExpandProperty Path
If found, use that file. Add the privacy opt-in call inside its
onCreate()
, after
super.onCreate()
.
Fallback: Launcher activity. If no Application class exists, find the launcher activity in
AndroidManifest.xml
— it is the
<activity>
that contains:
text
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
Read the
android:name
attribute of that activity, locate its source file, and add the privacy opt-in call inside
onCreate()
, after
setContentView(...)
.
Once the file is found, detect the language from its extension:
.kt
= Kotlin,
.java
= Java.
Do not assume the file is named
MainActivity
.
优先选择:Application类。使用对应系统的命令在源码树中搜索继承
Application
的类:
macOS / Linux:
bash
grep -r -l --include="*.java" "extends Application" APP_MODULE/src
grep -r -l --include="*.kt" ": Application()" APP_MODULE/src
Windows (cmd):
text
findstr /s /m "extends Application" APP_MODULE\src\*.java
findstr /s /m ": Application()" APP_MODULE\src\*.kt
Windows (PowerShell):
text
Get-ChildItem -Recurse -Path APP_MODULE/src -Include "*.java" | Select-String "extends Application" | Select-Object -ExpandProperty Path
Get-ChildItem -Recurse -Path APP_MODULE/src -Include "*.kt" | Select-String ": Application()" | Select-Object -ExpandProperty Path
若找到该文件,使用此文件。在其
onCreate()
方法中
super.onCreate()
之后添加隐私授权调用。
备选方案:启动Activity。若不存在Application类,在
AndroidManifest.xml
中查找启动Activity——即包含以下内容的
<activity>
标签:
text
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
读取该Activity的
android:name
属性,定位其源文件,并在
onCreate()
方法中
setContentView(...)
之后添加隐私授权调用。
找到文件后,根据扩展名判断语言:
.kt
= Kotlin,
.java
= Java。
请勿假设文件名为
MainActivity

Phase 5: Instrument

阶段5:执行插装配置

For each step below, check whether the element is already present before writing. If it is present and correct, skip it. If it is present but incorrect or incomplete, update only the affected values. If it is absent, add it in full.
Before editing any file, record its original content. If any step fails for any reason (build error, missing file, unresolvable conflict, unexpected file structure, etc.):
  1. Stop immediately — do not attempt further changes.
  2. Report the failure — state clearly which step failed and why.
  3. Rollback all edits — restore every file modified in this phase to its original content. If a file was created from scratch, delete it.
  4. Confirm rollback — tell the user which files were restored and that the project is back to its original state.
Do not leave the project in a partially instrumented state.
对于以下每一步,先检查元素是否已存在。若已存在且正确,则跳过;若已存在但不正确或不完整,则仅更新受影响的值;若不存在,则完整添加。
编辑任何文件前,记录其原始内容。若任何步骤因任何原因失败(构建错误、文件缺失、无法解决的冲突、意外的文件结构等):
  1. 立即停止——请勿尝试进一步修改。
  2. 报告失败——明确说明哪一步失败及原因。
  3. 回滚所有编辑——将此阶段修改的每个文件恢复为原始内容。若文件是全新创建的,则删除该文件。
  4. 确认回滚完成——告知用户哪些文件已恢复,项目已回到原始状态。
请勿让项目处于部分插装的状态。

Root build file

根构建文件

First check whether the root build file is
build.gradle.kts
(Kotlin DSL) or
build.gradle
(Groovy DSL) and apply the matching syntax.
com.dynatrace.instrumentation
must be applied in the root build file, not the app module.
首先检查根构建文件是
build.gradle.kts
(Kotlin DSL)还是
build.gradle
(Groovy DSL),并使用匹配的语法。
com.dynatrace.instrumentation
必须在根构建文件中应用,而非应用模块。

Kotlin DSL (
build.gradle.kts
)

Kotlin DSL (
build.gradle.kts
)

Classpath dependency — check whether
com.dynatrace.tools.android:gradle-plugin
already appears in a
buildscript { dependencies { } }
block. If yes and the version spec is
8.+
, skip. If yes with a different version, update the version to
8.+
. If absent, add the classpath into an existing
buildscript { dependencies { } }
block if one exists; otherwise add the full
buildscript
block before the
plugins {}
block:
text
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("com.dynatrace.tools.android:gradle-plugin:8.+")
    }
}
Plugin apply — check whether
apply(plugin = "com.dynatrace.instrumentation")
is already present. If yes, skip. If absent, add it after the
plugins {}
block.
DynatraceExtension block — check whether a
configure<com.dynatrace.tools.android.dsl.DynatraceExtension>
block already exists.
  • If it exists, check each field and update only those that differ from the target values:
    applicationId
    ,
    beaconUrl
    ,
    userOptIn(true)
    ,
    agentBehavior.startupLoadBalancing(true)
    ,
    agentBehavior.startupWithGrailEnabled(true)
    , and
    sessionReplay.enabled(true)
    (if session replay was requested). Add any missing fields.
  • If absent, add the full block after the plugin apply line. In both cases, substitute
    applicationId
    and
    beaconUrl
    with the values confirmed in Phase 3 — do not leave the placeholders below in place:
text
configure<com.dynatrace.tools.android.dsl.DynatraceExtension> {
    configurations {
        create("sampleConfig") {
            autoStart {
                applicationId("YOUR_APPLICATION_ID")
                beaconUrl("https://your-tenant.live.dynatrace.com/mbeacon")
            }
            userOptIn(true)
            agentBehavior.startupLoadBalancing(true)
            agentBehavior.startupWithGrailEnabled(true)
            // only if session replay was requested:
            sessionReplay.enabled(true)
        }
    }
}
类路径依赖——检查
com.dynatrace.tools.android:gradle-plugin
是否已出现在
buildscript { dependencies { } }
代码块中。若已存在且版本为
8.+
,则跳过;若已存在但版本不同,则将版本更新为
8.+
;若不存在,若已有
buildscript { dependencies { } }
代码块则添加类路径,否则在
plugins {}
代码块之前添加完整的
buildscript
代码块:
text
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("com.dynatrace.tools.android:gradle-plugin:8.+")
    }
}
插件应用——检查
apply(plugin = "com.dynatrace.instrumentation")
是否已存在。若已存在则跳过,若不存在则添加到
plugins {}
代码块之后。
DynatraceExtension代码块——检查
configure<com.dynatrace.tools.android.dsl.DynatraceExtension>
代码块是否已存在。
  • 若已存在,检查每个字段并仅更新与目标值不同的部分:
    applicationId
    beaconUrl
    userOptIn(true)
    agentBehavior.startupLoadBalancing(true)
    agentBehavior.startupWithGrailEnabled(true)
    ,以及(若请求启用会话重放)
    sessionReplay.enabled(true)
    。添加任何缺失的字段。
  • 若不存在,在插件应用行之后添加完整代码块。两种情况均需将
    applicationId
    beaconUrl
    替换为阶段3中确认的值——请勿保留以下占位符:
text
configure<com.dynatrace.tools.android.dsl.DynatraceExtension> {
    configurations {
        create("sampleConfig") {
            autoStart {
                applicationId("YOUR_APPLICATION_ID")
                beaconUrl("https://your-tenant.live.dynatrace.com/mbeacon")
            }
            userOptIn(true)
            agentBehavior.startupLoadBalancing(true)
            agentBehavior.startupWithGrailEnabled(true)
            // 仅当请求启用会话重放时添加:
            sessionReplay.enabled(true)
        }
    }
}

Groovy DSL (
build.gradle
)

Groovy DSL (
build.gradle
)

Classpath dependency — check whether
com.dynatrace.tools.android:gradle-plugin
already appears in a
buildscript { dependencies { } }
block. If yes and the version spec is
8.+
, skip. If yes with a different version, update the version to
8.+
. If absent, add the classpath inside the existing
buildscript { dependencies { } }
block, or create the full
buildscript
block before any
apply
lines if none exists:
text
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.dynatrace.tools.android:gradle-plugin:8.+'
    }
}
Plugin apply — check whether
apply plugin: 'com.dynatrace.instrumentation'
is already present. If yes, skip. If absent, add it after the existing
apply
lines or at the end of the file.
dynatrace block — check whether a
dynatrace { }
block already exists.
  • If it exists, check each field and update only those that differ from the target values:
    applicationId
    ,
    beaconUrl
    ,
    userOptIn true
    ,
    agentBehavior.startupLoadBalancing true
    ,
    agentBehavior.startupWithGrailEnabled true
    , and
    sessionReplay.enabled true
    (if session replay was requested). Add any missing fields.
  • If absent, add the full block after the plugin apply line. In both cases, substitute
    applicationId
    and
    beaconUrl
    with the values confirmed in Phase 3 — do not leave the placeholders below in place:
text
dynatrace {
    configurations {
        sampleConfig {
            autoStart {
                applicationId 'YOUR_APPLICATION_ID'
                beaconUrl 'https://your-tenant.live.dynatrace.com/mbeacon'
            }
            userOptIn true
            agentBehavior.startupLoadBalancing true
            agentBehavior.startupWithGrailEnabled true
            // only if session replay was requested:
            sessionReplay.enabled true
        }
    }
}
类路径依赖——检查
com.dynatrace.tools.android:gradle-plugin
是否已出现在
buildscript { dependencies { } }
代码块中。若已存在且版本为
8.+
,则跳过;若已存在但版本不同,则将版本更新为
8.+
;若不存在,若已有
buildscript { dependencies { } }
代码块则添加类路径,否则在所有
apply
行之前创建完整的
buildscript
代码块:
text
buildscript {
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath 'com.dynatrace.tools.android:gradle-plugin:8.+'
    }
}
插件应用——检查
apply plugin: 'com.dynatrace.instrumentation'
是否已存在。若已存在则跳过,若不存在则添加到现有
apply
行之后或文件末尾。
dynatrace代码块——检查
dynatrace { }
代码块是否已存在。
  • 若已存在,检查每个字段并仅更新与目标值不同的部分:
    applicationId
    beaconUrl
    userOptIn true
    agentBehavior.startupLoadBalancing true
    agentBehavior.startupWithGrailEnabled true
    ,以及(若请求启用会话重放)
    sessionReplay.enabled true
    。添加任何缺失的字段。
  • 若不存在,在插件应用行之后添加完整代码块。两种情况均需将
    applicationId
    beaconUrl
    替换为阶段3中确认的值——请勿保留以下占位符:
text
dynatrace {
    configurations {
        sampleConfig {
            autoStart {
                applicationId 'YOUR_APPLICATION_ID'
                beaconUrl 'https://your-tenant.live.dynatrace.com/mbeacon'
            }
            userOptIn true
            agentBehavior.startupLoadBalancing true
            agentBehavior.startupWithGrailEnabled true
            // 仅当请求启用会话重放时添加:
            sessionReplay.enabled true
        }
    }
}

Entry-point file (Application class or launcher activity)

入口文件(Application类或启动Activity)

Add only the imports not already present. For the privacy opt-in call, check whether
Dynatrace.applyUserPrivacyOptions(...)
already exists inside
onCreate
. If yes, verify each option (
DataCollectionLevel.USER_BEHAVIOR
,
withCrashReportingOptedIn(true)
,
withScreenRecordOptedIn(true)
if session replay is enabled) and update any that differ. If absent, insert it at the position matching the entry-point type:
  • Application subclass — after
    super.onCreate()
  • Launcher activity — after
    setContentView(...)
仅添加尚未存在的导入。对于隐私授权调用,检查
Dynatrace.applyUserPrivacyOptions(...)
是否已存在于
onCreate
方法中。若已存在,验证每个选项(
DataCollectionLevel.USER_BEHAVIOR
withCrashReportingOptedIn(true)
,以及若启用会话重放则
withScreenRecordOptedIn(true)
)并更新任何不同的部分。若不存在,根据入口文件类型插入到对应位置:
  • Application子类——
    super.onCreate()
    之后
  • 启动Activity——
    setContentView(...)
    之后

Kotlin

Kotlin

Imports — add only those not already present:
text
import com.dynatrace.android.agent.Dynatrace
import com.dynatrace.android.agent.conf.DataCollectionLevel
import com.dynatrace.android.agent.conf.UserPrivacyOptions
Privacy opt-in call — insert after
super.onCreate()
(Application subclass) or after
setContentView(...)
(launcher activity). Include
.withScreenRecordOptedIn(true)
only if session replay was enabled in Phase 3:
text
Dynatrace.applyUserPrivacyOptions(
    UserPrivacyOptions.builder()
        .withDataCollectionLevel(DataCollectionLevel.USER_BEHAVIOR)
        .withCrashReportingOptedIn(true)
        // .withScreenRecordOptedIn(true) — add only if session replay is enabled
        .build()
)
导入——仅添加尚未存在的导入:
text
import com.dynatrace.android.agent.Dynatrace
import com.dynatrace.android.agent.conf.DataCollectionLevel
import com.dynatrace.android.agent.conf.UserPrivacyOptions
隐私授权调用——插入到
super.onCreate()
之后(Application子类)或
setContentView(...)
之后(启动Activity)。仅当阶段3中启用会话重放时添加
.withScreenRecordOptedIn(true)
text
Dynatrace.applyUserPrivacyOptions(
    UserPrivacyOptions.builder()
        .withDataCollectionLevel(DataCollectionLevel.USER_BEHAVIOR)
        .withCrashReportingOptedIn(true)
        // .withScreenRecordOptedIn(true) ——仅当启用会话重放时添加
        .build()
)

Java

Java

Imports — add only those not already present:
text
import com.dynatrace.android.agent.Dynatrace;
import com.dynatrace.android.agent.conf.DataCollectionLevel;
import com.dynatrace.android.agent.conf.UserPrivacyOptions;
Privacy opt-in call — insert after
super.onCreate()
(Application subclass) or after
setContentView(...)
(launcher activity). Include
.withScreenRecordOptedIn(true)
only if session replay was enabled in Phase 3:
text
Dynatrace.applyUserPrivacyOptions(UserPrivacyOptions.builder()
    .withDataCollectionLevel(DataCollectionLevel.USER_BEHAVIOR)
    .withCrashReportingOptedIn(true)
    // .withScreenRecordOptedIn(true) — add only if session replay is enabled
    .build()
);
导入——仅添加尚未存在的导入:
text
import com.dynatrace.android.agent.Dynatrace;
import com.dynatrace.android.agent.conf.DataCollectionLevel;
import com.dynatrace.android.agent.conf.UserPrivacyOptions;
隐私授权调用——插入到
super.onCreate()
之后(Application子类)或
setContentView(...)
之后(启动Activity)。仅当阶段3中启用会话重放时添加
.withScreenRecordOptedIn(true)
text
Dynatrace.applyUserPrivacyOptions(UserPrivacyOptions.builder()
    .withDataCollectionLevel(DataCollectionLevel.USER_BEHAVIOR)
    .withCrashReportingOptedIn(true)
    // .withScreenRecordOptedIn(true) ——仅当启用会话重放时添加
    .build()
);

Phase 6: Build and verify

阶段6:构建并验证

First, discover available assemble tasks to handle projects with custom build types or product flavors:
macOS / Linux:
bash
./gradlew tasks --group=build | grep -i "^assemble"
Windows (cmd):
text
gradlew.bat tasks --group=build | findstr /i "assemble"
Windows (PowerShell):
text
.\gradlew.bat tasks --group=build | Select-String -Pattern "^assemble" -CaseSensitive:$false
If only one assemble task is listed, use it. If multiple tasks are listed, present them to the user and ask which one to run.
Then run it:
  • macOS / Linux:
    ./gradlew CHOSEN_TASK
  • Windows (cmd):
    gradlew.bat CHOSEN_TASK
  • Windows (PowerShell):
    .\gradlew.bat CHOSEN_TASK
A successful build confirms the Dynatrace plugin is wired up correctly.
首先,发现可用的assemble任务以处理包含自定义构建类型或产品风味的项目:
macOS / Linux:
bash
./gradlew tasks --group=build | grep -i "^assemble"
Windows (cmd):
text
gradlew.bat tasks --group=build | findstr /i "assemble"
Windows (PowerShell):
text
.\gradlew.bat tasks --group=build | Select-String -Pattern "^assemble" -CaseSensitive:$false
若仅列出一个assemble任务,使用该任务。若列出多个任务,将其展示给用户并询问运行哪一个。
然后运行选中的任务:
  • macOS / Linux:
    ./gradlew CHOSEN_TASK
  • Windows (cmd):
    gradlew.bat CHOSEN_TASK
  • Windows (PowerShell):
    .\gradlew.bat CHOSEN_TASK
构建成功即确认Dynatrace插件已正确配置。