# 客户端 SDK 常见问题

# 客户端 SDK 上报策略是什么?

原生客户端 SDK (包括 Unity、Unreal、Flutter 等) 数据会首先缓存在本地数据库,并在以下情况触发数据上报:

  • App 退到后台
  • 1 分钟上报一次(可以在 TA 后台设置)
  • 缓存数据超过 100 条触发上报(可以在 TA 后台设置)
  • 主动调用 flush 接口

小程序、小游戏 SDK,以及 JavaScript SDK 会实时上报,没有本地缓存。

# 设备 ID 的取值逻辑是什么?

原生客户端 SDK (包括 Unity、Unreal、Flutter 等) 的设备 ID 取值逻辑如下:

  • Android: 取 Android ID

    对于 Android 8.0 以下的系统,Android ID 是设备唯一标识。重新刷机或者恢复出厂设置才会变更。所有应用共享。Android 8.0 及之后的系统,应用签署密钥、用户和设备的每个组合都具有唯一的 ANDROID_ID 值。因此,在相同设备上运行但具有不同签署密钥的应用将不会再看到相同的 Android ID(即使对于同一用户来说,也是如此)。一个特殊情况:如果用户安装 APP 设备是 8.0 以下,后来卸载了,升级到 8.0 之后又重装了应用,Android ID 会跟之前不一样;如果没有重装,那么 Android ID 不会变更。

  • iOS:先取 IDFV,如果取不到就用随机 UUID。首次取的 设备 ID 值将存入钥匙串中,不再改变,即使 后续 IDFV 发生变化。

小程序、小游戏和 JavaScript 接口无法取得类似的设备号,使用一个随机生成的 ID 作为设备 ID。如果用户删除了缓存,该设备 ID 将会发生变化。

# 客户端 SDK 支持的最低系统版本是多少?

客户端 SDK 支持的最低版本是 Android 4.0 和 iOS 8.0

# 如何排查上报问题?

一般问题可以通过客户端日志很快定位,我们在各个接入指南中都介绍了如何开启客户端日志。

在 Android 中,您可以通过调用 enableTrackLog 接口来开启客户端日志。您可以通过 ThinkingAnalytics 来过滤 Android SDK 的日志。

ThinkingAnalyticsSDK.enableTrackLog(true);

在 iOS 中,您可以通过调用 setLogLevel 接口来开启日志打印,并通过 THINKING 来过滤 iOS SDK 的日志。

[ThinkingAnalyticsSDK setLogLevel:TDLoggingLevelDebug]

在打开日志后,您可以将日志发给我们的技术支持工程师,协助定位问题 。

如果您不确定上报地址是否正确,可以通过检查检查接口来检测上报地址的可达性。 访问 https://YOUR_RECEIVER_URL/health-check,页面返回 ok 表示接收端地址配置正确。

除此之外,通过埋点管理模块的功能,也可以方便的定位到数据上报过程中的问题。

# 通过 Unity SDK 上报数据有哪些注意事项?

  1. 我们的 SDK 的初始化是在 Awake() 中完成的,因此调用不可以在 Awake 中触发
  2. 默认情况下所有接口只能在主线程中调用。
  3. 我们是通过 Android 系统的组件生命周期来判断 APP 是否进入前台或者退到后台的。但是 Unity 中无法保证在程序最开始就初始化 SDK,所以可能会在退到后台的时候才能判断初次启动事件。目前我们会在第一次退到后台的时候补一个 ta_app_start(上报略晚,但是事件时间 #event_time 是正确的,不影响后续分析)

# 崩溃事件包括哪些内容?如何采集崩溃事件

客户端 SDK 支持部分崩溃日志的采集。需要在初始化 SDK 之后,开启 APP Crash 的自动采集。崩溃事件对应的事件名为:ta_app_crash。

触发崩溃事件采集的情况:

  • Android 平台:虚拟机中出现未捕获异常
  • iOS 平台:
    • Unix 信号异常 包括:SIGABRT, SIGILL, SIGSEGV, SIGFPE, SIGBUS
    • NSException 异常

# Android 自动采集事件问题排查?

大部分自动采集事件都只需要调用 enableAutoTrack 接口即可。 如果您需要采集控件点击事件,或者 Fragment 浏览事件,则需要应用 TA 提供的自动采集插件,请参考Android SDK 自动采集指南一章。

如果您使用了自动采集插件,并出现编译错误,有可能是我们的插件与某些 package 冲突造成的。大多数时候只需要找到日志中的提示的出错的包名,并在 gradle 配置中添加以下内容(以 com.alipay 为例),即可解决:

thinkingAnalytics {
    exclude 'com.alipay'
}

如果您的项目使用了 MultiDex,有可能会遇到 ClassNotFoundException 的错误,这种情况需要将报错的类打包到主 dex,并且要确保我们 SDK 的代码打包到主 dex 中, 在 multiDexKeepProguard 里添加如下配置:

-keep class cn.thinkingdata.android.** { *; }