移动端无痕埋点实践详解(二)

移动端无痕埋点实践详解(一)这篇文章大致总结了移动端无痕埋点的基本原理。主要介绍了什么是无痕埋点,无痕埋点的基础数据流程以及在Android系统上总体思路。这篇文章着重总结下无痕埋点方案的实施过程中在Android和iOS系统上几个细节的解决方案。

0x02 xpath

2.1 什么是xpath

xpath是移动端定义可操作区域的数字标识,是用来标识可操作的控件的。既然想要通过一串字符标识在移动端app中的可操作控件,那么xpath的生成规则需要满足以下几个原则:

  • 唯一性: 在当前app中不存在不同控件对应相同Xpath
  • 稳定性: 不同版本app中,在没有页面结构变更的情况下,不同版本中相同页面中相同控件的Xpath要保持不变

2.1 Android中如何生成xpath

在满足上述xpath原则的基础上,可通过以下几个参数作为组成XPath的生成参数:

  • 页面:标记当前控件所在的页面url,Webview页面为其html的url,native页面url可定义该页面的virtual url
  • 页面中位置:如何描述一个控件在该页面的位置,在Android系统中很容易想到DecorView和页面子view的关系。使用View到DecorView的位置关系来描述视图控件在该页面中的相对位置。

Alt text

  • 控件标记:这里的控件标记指的是相对于相同父容器的兄弟视图来说,如何更好的区别彼此。这里很容易能够想到view id。但是这里并不推荐使用view id作为标记。因为id是在版本迭代过程中很容易因为资源数量的变化而发生变化。并不能满足标记稳定性的原则,目前在Android上我选择resource name作为视图控件的标记。在ios上

综上所述就可以得到以下的XPath生成方式。

$ xpath = Md5(url+root path + resource name)$

2.2 iOS系统中如何生成xpath

参考 https://www.jianshu.com/p/69ce01e15042

2.3 如何识别xpath

在用户产生用户点击数据的过程中,埋点系统上报控件xpath给埋点后台,但是在实际的数据分析过程中需要知道每个xpath对应的控件和区块名称具体是什么。在每个电商系统中针对埋点都会有一套自己的位置模型规范,简称SPM(super position model)。所以针对最终的数据分析和统计需要一个xpath到spm的映射关系,将实际产生的xpath埋点数据转换成业务中的SPM。实现方式也很简单,只需要在开发版本中提供一个编辑模式,将移动端本地生成的xpath通过一个编辑工具转换成SPM数据就可以了,简单的效果图如下所示:

Alt text

0x03 Android如何记录页面跳转

在考虑记录页面跳转的方案时,可能最先想到的是在通过统一路由跳转的方式跟踪所有页面跳转,但是实际的项目中首先你得有个统一的路由不是?在面对已有的项目代码从工作量和效果上来说这种方式都不是最佳方案。即便是已有统一的路由方案也很难保证没有错埋漏埋的情况存在。别忘记 ActivityLifecycleCallbacks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class RuntimeActivityCallbacks implements Application.ActivityLifecycleCallbacks {

private Map<String, Long> mPageResumeTime = new HashMap<>();

/**
* 页面对应的referrerId,一个activity可能有多个子页面,一个activity的referrerId为当前显示的子页面的referrerId
*/
private Map<Integer, String> mPageReferrerMap = new HashMap<>();

@Override
public void onActivityResumed(Activity activity) {
// 针对页面的跟踪
if (activity instanceof IPageTracker) {
IPageTracker pageTracker = (IPageTracker) activity;
String url = pageTracker.getReferrerId();

mPageResumeTime.put(url, System.currentTimeMillis());
mPageReferrerMap.put(activity.hashCode(), url);
AppTraceTool.traceOpenPage(url, ModuleManager.getTopPageUrl());

// 保存当前页面为top
ModuleManager.setTopPageUrl(url);
} else {
ModuleManager.setTopPageUrl("unknown");
}
}

@Override
public void onActivityStopped(Activity activity)
// 针对页面的跟踪
if (activity instanceof IPageTracker) {
IPageTracker pageTracker = (IPageTracker) activity;
String url = pageTracker.getReferrerId();
mPageResumeTime.remove(url);
mPageReferrerMap.remove(activity.hashCode());
AppTraceTool.traceLeavePage(url, second);
}
}
}

0x04 如何使用无痕埋点方案记录业务数据

转载请标明出处病已blog https://ivonhoe.github.io/