全埋点,也叫无埋点、无码埋点、自动埋点。全埋点是指预先收集用户的所有行为数据,然后再根据实际分析需求从中提取行为数据。

全埋点采集的事件主要包括下面四种:

• $AppStart 事件:指 App 启动,包括冷启动和热启动。

• $AppEnd 事件:指 App 退出,包括正常退出、进入后台、 App 崩溃、App 被强杀。

• $AppViewScreen 事件:指 App 页面浏览 ,对于 Android 来说,就是指切换 Activity。

• $AppClick 事件:指 App 控件被点击。

在采集的这四种事件当中,最重要并且采集难度最大的是 $AppClick 事件。所以,全埋点基本上也都是围绕着如何采集 $AppClick 事件。

全埋点的整体解决思路,就是要找到那个被点击的 View 的点击处理逻辑(也叫原处理逻辑),然后利用一定的技术原理,对原处理逻辑进行“拦截”,或者在原处理逻辑的前面或者后面“插入”相应的埋点代码,从而达到自动埋点的效果。

至于如何做到自动“拦截”View 的原点击处理逻辑,一般都是参考 Android 系统 View 点击事件处理机制来进行的。 至于如何做到自动“插入”埋点代码,基本上都是参考编译器对 Java 代码的处理流程来进行的即:

JavaCode --> .java --> .class --> .dex

选择在不同的处理阶段“插入”代码,其所用的技术或者原理也不尽相同,所以全埋点的解决方案也是多种多样的。

面对这么多的全埋点方案,我们究竟该如何选择呢?

在选择全埋点的方案时,需要从效率、兼容性、扩展性等 方面综合考虑。

• 效率

全埋点的基本原理,其实就是利用某些技术对某些方法 (View 被点击时的处理逻辑)进行代理(或者叫 Hook),或者“插入”代码。按照“在什么时候去代理或者插入代码” 这个条件来区分的话,Android 全埋点技术可以大致分为 下面两种方式 :

静态代理

所谓静态,就是指通过 Gradle Plugin 在编译期间“插入” 或者修改代码(.class 文 件)。比如 AspectJ、ASM、javassist、AST 等方案均是这种方式,我们后面介绍的第四种方案到第七种方案均属于静态代理。

这几种方式处理的时机可以参考下图:

动态代理

所谓动态,就是指在代码运行的时候去进行代理。比如我们比较常见的代理 View.OnClickListener、Window.Call- back、View.AccessibilityDelegate 等方案均是这种方式。我们后面介绍的第一种方案到第三种方案均属于动态代理。

不同的方案,其处理、运行效率也各不相同,同时对 App的浸入程度以及对 App 的整体性能的影响也各不相同。整理上来说,静态代理明显优于动态代理,这是因为静态代理的“动 作”是在 App 的编译阶段处理的,不会对 App 的正常业务(App 运行时)逻辑有太大的影响。

• 兼容性

随着 Android 生态系统的快速发展,不管是 Android 系统本身,还是与 Android App 开发相关的组件和技术,都在飞速 发展快速迭代,从而也给研发全埋点方案带来一定的难度。比如不同的 Android App 有不同的开发语言(Java 、Kotlin)、 也有不同的 Java 版本(Java7、Java8)、也有不同的开发 IDE(eclipse、Android Studio)、更有不同的开发方式(原生开发、 H5、混合开发)、不同的第三方开发框架(React Native、APICloud、Weex)、不同的 Gradle 版本、以及 Lambda、D8、 Instant Run、DataBinding、Fragment 等,都会给全埋点带来很多兼容性方面的问题。

• 扩展性

随着业务的发展和数据分析需求的不断提高,即使对于全埋点,也提出了更高的采集要求。一方面要求能全部自动埋点(采 集的范围),同时又要求能有更精细化的采集控制(采集自定义)。比如,如何给某个控件添加自定义属性 ?如果不想采集 某个控件的点击事件如何处理 ?如果不想采集某种控件类型(ImageView)的点击事件如何处理 ?如果某个页面 (Activity)上所有控件的点击事件都不想采集如何处理 ?...... 任何一种全埋点的方案,都有其优点和缺点。没有普适的完美方案。针对不同的应用场景,选择最合适的数据采集方案即可。

注:该内容来自神策数据用户行为洞察研究院出品的《Android 全埋点解决方案》白皮书,查看完整白皮书可点击《Android 全埋点解决方案》

更多白皮书、报告、干货和案例,可以关注“神策数据”和“用户行为洞察研究院”公众号了解~