一、前言
在运营分析中,DAU(Daily Active User)、UV(Unique Visitor)和用户使用时长是最常见的三个指标。对于一个 App 来说,三个指标的含义如下:
-
DAU:日活跃用户数;
-
UV:独立访客;
-
用户使用时长:App 使用时长。
根据上面的描述可知,DAU 和 UV 的统计分析与 App 启动事件息息相关,用户使用时长则需要通过 App 退出事件进行分析。
在神策分析中,统计上述三个指标的方式如下:
-
DAU:通过查询 App 每日启动的独立用户数来统计;
-
UV:通过查询 App 启动总的用户数来统计;
-
用户使用时长:通过查询 App 退出事件平均时长来统计。
神策 Android SDK[1] 已经开源四年多了,这段时间内已经陆续发布了近 160 个版本,从最初的仅支持代码埋点到现在支持全埋点、可视化全埋点等功能。其中,全埋点的启动事件和退出事件采集也经过了不断地演进,作者作为方案设计的参与者整理了整个过程。下面逐步向大家进行介绍,希望对大家有所帮助,更希望得到一些指导意见。
二、基本原理
因为在 Android 系统中没有开放的 API 接口监听 App 的启动与退出,所以无法直接从系统层面精确地判断 App 的启动与退出。在 Android 中 App 的页面承载是基于 Activity,因此可以尝试从 Activity 启动个数的维度来判断 App 的启动和退出。
总的来说,当监测到第一个 Activity 打开的时候标记为 App 启动;监测到最后一个 Activity 页面关闭的时候标记为 App 退出。
在 Android 系统中,可以通过在 Application 中注册 Application.ActivityLifecycleCallbacks 回调来统计 Activity 的切换,从而达到对 App 启动和退出事件的埋点采集,代码如下:
ActivityLifecycleCallbacks
public interface ActivityLifecycleCallbacks {
void onActivityCreated(@NonNull Activity activity, @Nullable Bundle savedInstanceState);
void onActivityStarted(@NonNull Activity activity);
void onActivityResumed(@NonNull Activity activity);
void onActivityPaused(@NonNull Activity activity);
void onActivityStopped(@NonNull Activity activity);
void onActivityDestroyed(@NonNull Activity activity);
}
代码释义如下:
-
onActivityCreated:当 Activity 调用 super.onCreate() 时触发;
-
onActivityStarted:当 Activity 调用 super.onStart() 时触发;
-
onActivityResumed:当 Activity 调用 super.onResume() 时触发;
-
onActivityPaused:当 Activity 调用 super.onPause() 时触发;
-
onActivityStopped:当 Activity 调用 super.onStop() 时触发;
-
onActivityDestroyed:当 Activity 调用 super.onDestroy() 时触发。
三、方案演进
3.1 初期版本 1.0
3.1.1. 原理简介
在初期版本中,通过监测 Activity 的 onStart 和 onStop 生命周期函数来判断 App 启动和退出:
1. 在 SDK 初始化时注册 Application.ActivityLifecycleCallbacks 监听,同时内部维护一个 Activity 的计数器;
2. 当触发 onActivityStarted 回调时,如果 Activity 计数器个数为 0,则表示 App 打开的第一个页面(即 App 启动)。此时,触发 App 启动事件,同时计数器加 1;
3. 当触发 onActivityStopped 回调时,表示一个 Activity 页面不可见,则 Activity 计数器减 1。如果 Activity 计数器个数为 0,则表示 App 最后一个页面不可见(即 App 退出)。此时,触发 App 退出事件。
核心流程如图 3-1 所示:
图 3-1 初期版本的流程图
3.1.2. 具体实现
针对初期版本的启动退出事件采集的核心逻辑,代码示例如下:
核心逻辑实现
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
registerActivityLifecycleCallbacks(new SensorsDataActivityLifecycleCallbacks());
}