跳转到主要内容
本文档介绍 Android RUM SDK 的异常捕获机制,帮助您监控和诊断 Android 应用中的崩溃和错误问题。
SDK 支持自动捕获 Java/Kotlin 崩溃、NDK 原生崩溃、ANR(应用无响应),同时提供手动错误上报和符号化堆栈跟踪功能。

异常类型

Android RUM 可以监控以下类型的异常:

Java/Kotlin 崩溃

SDK 自动捕获未处理的 Java/Kotlin 异常,包括:
  • 运行时异常(如 NullPointerExceptionIndexOutOfBoundsException
  • 未捕获的异常
  • 应用崩溃

NDK 崩溃(Native Crash)

若您的应用使用了原生代码(C/C++),SDK 支持捕获 NDK 崩溃并将其纳入异常追踪。

ANR(应用无响应)

SDK 可以检测并报告 ANR 问题,帮助您发现主线程阻塞导致的用户体验问题。

自定义错误

除了自动捕获的异常外,您还可以使用 RUM SDK 手动上报自定义异常,用于跟踪业务逻辑错误等特定问题。

配置崩溃报告

基础配置

崩溃报告功能默认启用。确保您已按照 SDK 接入指南 完成基础 SDK 集成后,SDK 会自动捕获应用中的未处理异常。

添加 NDK 崩溃报告

若您的应用包含原生代码(C/C++),需要添加 NDK 崩溃报告模块来捕获原生崩溃。
1

添加依赖

在您的应用模块的 build.gradle 文件中添加 NDK 崩溃报告依赖:
build.gradle
dependencies {
    implementation "cloud.flashcat:fc-sdk-android-ndk:0.1.0"
}
2

启用 NDK 崩溃报告

在 SDK 初始化后启用 NDK 崩溃报告:
import cloud.flashcat.android.ndk.NdkCrashReports

// 在 Flashcat.initialize() 之后调用
NdkCrashReports.enable()

添加 ANR 报告

ANR(Application Not Responding)是指应用主线程被阻塞超过一定时间,导致应用无法响应用户输入的情况。

启用 ANR 检测

在 RUM 配置中启用 ANR 检测:
import cloud.flashcat.android.rum.RumConfiguration

val rumConfig = RumConfiguration.Builder(applicationId)
    .trackNonFatalAnrs(true) // 追踪非致命 ANR
    .build()
ANR 检测会监控主线程的响应性。当检测到主线程阻塞超过阈值时,SDK 会自动记录 ANR 事件。

手动错误上报

通过 addError API,您可以手动上报已处理的异常、自定义错误或其他未被自动捕获的错误。

上报错误示例

import cloud.flashcat.android.rum.GlobalRum
import cloud.flashcat.android.rum.RumErrorSource

// 上报带有上下文的错误
try {
    riskyOperation()
} catch (e: Exception) {
    GlobalRum.get().addError(
        message = "操作失败",
        source = RumErrorSource.SOURCE,
        throwable = e,
        attributes = mapOf(
            "operation" to "riskyOperation",
            "userId" to "12345"
        )
    )
}

错误来源类型

RumErrorSource 可选值:
描述
RumErrorSource.NETWORK网络错误
RumErrorSource.SOURCE源码错误
RumErrorSource.CONSOLE控制台错误
RumErrorSource.LOGGER日志错误
RumErrorSource.AGENTAgent 错误
RumErrorSource.WEBVIEWWebView 错误
RumErrorSource.CUSTOM自定义错误

上报网络错误示例

import cloud.flashcat.android.rum.GlobalRum
import cloud.flashcat.android.rum.RumErrorSource

fun onNetworkError(url: String, statusCode: Int, error: Throwable) {
    GlobalRum.get().addError(
        message = "网络请求失败: $url",
        source = RumErrorSource.NETWORK,
        throwable = error,
        attributes = mapOf(
            "url" to url,
            "status_code" to statusCode,
            "method" to "GET"
        )
    )
}

获取脱混淆的堆栈跟踪

如果您的应用启用了代码混淆(ProGuard/R8),上报的崩溃堆栈将被混淆。通过上传 mapping 文件,可以将混淆后的堆栈还原为原始的类名、方法名和行号。

配置 Gradle 插件

1

添加插件依赖

在项目根目录的 build.gradle 文件中添加 Flashcat Gradle 插件:
build.gradle
buildscript {
    dependencies {
        classpath "cloud.flashcat:fc-gradle-plugin:0.1.0"
    }
}
2

应用插件

在应用模块的 build.gradle 文件中应用插件:
build.gradle
plugins {
    id 'cloud.flashcat.android'
}
3

配置插件

build.gradle 文件中配置 Flashcat 插件:
build.gradle
flashcat {
    site = "FLASHCAT_SITE"         // 数据上报站点
    clientToken = "<CLIENT_TOKEN>" // 客户端令牌
    serviceName = "<SERVICE_NAME>" // 服务名称(可选)
    versionName = "1.0.0"          // 应用版本(可选,默认取 android.defaultConfig.versionName)
}

上传 Mapping 文件

配置完成后,插件会在构建过程中自动上传 mapping 文件。您也可以手动运行上传任务:
./gradlew uploadMapping<Variant>
例如,对于 release 变体:
./gradlew uploadMappingRelease

上传 NDK 符号文件

如果您使用了 NDK 崩溃报告,还需要上传 NDK 符号文件以获取可读的原生堆栈:
./gradlew uploadNdkSymbolFiles<Variant>

插件配置选项

属性名描述
versionName应用版本名称(默认取 android 块中声明的版本)
serviceName服务名称(默认取应用包名)
site数据上报站点
checkProjectDependencies控制插件是否检查 Flashcat SDK 依赖。可选值:none(忽略)、warn(警告)、fail(失败,默认)

Mapping 文件大小限制

Mapping 文件大小限制为 500 MB。如果文件过大,可以使用以下选项减小文件大小:
build.gradle
flashcat {
    mappingFileTrimIndents = true  // 移除缩进,平均减少约 5% 的文件大小

    mappingFilePackageAliases = [
        "kotlinx.coroutines": "kx.cor",
        "com.google.android.material": "material",
        "com.google.gson": "gson"
    ]
}
使用 mappingFilePackageAliases 时,Flashcat 异常追踪中的堆栈将使用别名替代原始包名。建议仅对第三方依赖使用此选项。

追踪后台事件

默认情况下,只有在视图处于活动状态时发生的崩溃才会被追踪。如果您希望追踪应用在后台时发生的崩溃,可以启用后台事件追踪:
import cloud.flashcat.android.rum.RumConfiguration

val rumConfig = RumConfiguration.Builder(applicationId)
    .trackBackgroundEvents(true)
    .build()
追踪后台事件可能会产生额外的会话,这可能会影响计费。如有疑问,请联系 Flashcat 支持团队。

限制与注意事项

崩溃检测限制

  • SDK 初始化时机:崩溃只有在 SDK 初始化之后才能被检测到。建议在 Application.onCreate() 中尽早初始化 SDK。
  • 视图关联:崩溃必须与一个 RUM 视图关联。若在视图显示前或应用被置于后台后发生崩溃,该崩溃可能不会被报告。可通过 trackBackgroundEvents(true) 缓解这一问题。
  • 采样率影响:只有被采样的会话中的崩溃才会被保留。如果会话采样率不是 100%,部分崩溃可能不会被报告。

符号化限制

  • 确保 mapping 文件在每次发布新版本时都正确上传。
  • 不同构建变体(如 debug/release)需要分别上传对应的 mapping 文件。
  • NDK 符号文件需要包含调试信息才能正确符号化。

测试验证

验证 Java/Kotlin 崩溃

  1. 在应用中添加测试代码触发崩溃:
fun onEvent() {
    throw RuntimeException("测试崩溃")
}
  1. 运行应用并触发崩溃
  2. 重启应用,等待 SDK 上传崩溃报告
  3. 在 Flashcat 控制台的异常追踪模块中查看崩溃报告

验证 NDK 崩溃

  1. 在原生代码中添加测试崩溃:
void crash() {
    int* ptr = nullptr;
    *ptr = 42;  // 触发空指针崩溃
}
  1. 从 Java/Kotlin 代码调用该原生方法
  2. 重启应用,等待 SDK 上传崩溃报告
  3. 确认堆栈是否已被正确符号化(显示函数名、文件名和行号)

验证 ANR

  1. 在主线程执行耗时操作:
fun blockMainThread() {
    Thread.sleep(10000)  // 阻塞主线程 10 秒
}
  1. 触发该操作后尝试与应用交互
  2. 检查 Flashcat 控制台是否收到 ANR 报告

错误数据结构

每条错误数据包含以下属性:
属性类型描述
error.sourcestring错误来源(如 sourcenetworkcustom
error.typestring错误类型或错误码(如 NullPointerException
error.messagestring错误消息
error.stackstring错误堆栈跟踪
error.is_crashboolean是否为崩溃
contextObject自定义上下文信息,通过 addErrorattributes 传入

最佳实践

  1. 尽早初始化 SDK:在 Application.onCreate() 中初始化 SDK,确保能捕获尽可能多的崩溃。
  2. 启用后台事件追踪:如果您的应用有大量后台操作,建议启用 trackBackgroundEvents
  3. 正确上传符号文件
    • 为每个发布版本上传对应的 mapping 文件
    • 如果使用 NDK,同时上传 NDK 符号文件
    • 在 CI/CD 流程中集成符号文件上传
  4. 丰富错误上下文:在手动上报错误时,附加业务相关的上下文信息(如用户 ID、操作类型)。
  5. 过滤无关错误:使用 setErrorEventMapper 过滤第三方 SDK 或无关的错误,减少噪音。

下一步