第1章 全埋点概述
全埋点,也叫无埋点、无码埋点、无痕埋点、自动埋点。全埋点是指无须Android应用程序开发工程师写代码或者只写少量的代码,就能预先自动收集用户的所有行为数据,然后就可以根据实际的业务分析需求从中筛选出所需行为数据并进行分析。
全埋点采集的事件目前主要包括以下四种(事件名称前面的$符号,是指该事件是预置事件,与之对应的是自定义事件)。
·$AppStart事件
是指应用程序启动,同时包括冷启动和热启动场景。热启动也就是指应用程序从后台恢复的情况。
·$AppEnd事件
是指应用程序退出,包括应用程序的正常退出、按Home键进入后台、应用程序被强杀、应用程序崩溃等场景。
·$AppViewScreen事件
是指应用程序页面浏览,对于Android应用程序来说,就是指切换Activity或Fragment。
·$AppClick事件
是指应用程序控件点击,也即View被点击,比如点击Button、ListView等。
在采集的这四种事件当中,最重要并且采集难度最大的是$AppClick事件。所以,全埋点的解决方案基本上也都是围绕着如何采集$AppClick事件来进行的。
对于$AppClick事件的全埋点整体解决思路,归根结底,就是要自动找到那个被点击的控件处理逻辑(后文统称原处理逻辑),然后再利用一定的技术原理,对原处理逻辑进行“拦截”,或者在原处理逻辑的执行前面或执行者后面“插入”相应的埋点代码逻辑,从而达到自动埋点的效果。
至于如何做到自动“拦截”控件的原处理逻辑,一般都是参考Android系统的事件处理机制来进行的。关于Android系统的事件处理机制,本书由于篇幅有限,不再详述。
至于如何做到自动“插入”埋点代码逻辑,基本上都是参考编译器对Java代码的整体处理流程来进行的,即:
JavaCode --> .java --> .class --> .dex
选择在不同的处理阶段“插入”埋点代码,所采用的技术或者原理也不尽相同,所以全埋点的解决方案也是多种多样的。
面对这么多的全埋点方案,我们究竟该如何做选择呢?
在选择全埋点的解决方案时,我们需要从效率、兼容性、扩展性等方面进行综合考虑。
·效率
全埋点的基本原理,如上所述,其实就是利用某些技术对某些方法(控件被点击时的处理逻辑)进行拦截(或者叫代理)或者“插入”相关埋点代码。比如按钮Button,如果要给它设置点击处理逻辑,需要设置android.view.View.OnClickListener,并重写它的onClick(android.view.View)方法。如果要实现$AppClick事件的全埋点,我们就可以“拦截”onClick(android.view.View)方法,或者在onClick(android.view.View)方法的前面或者后面“插入”相应的埋点逻辑代码。按照“在什么时候去代理或者插入代码”这个条件来区分的话,$AppClick事件的全埋点技术可以大致分为如下两种方式。
·静态代理
所谓静态代理,就是指通过Gradle Plugin在应用程序编译期间“插入”代码或者修改代码(.class文件)。比如AspectJ、ASM、Javassist、AST等方案均属于这种方式。这几种方案,我们在后面会一一进行介绍。
这几种方式处理的时机可以参考图1-1。
图1-1 静态代理处理时机
·动态代理
所谓动态代理,就是指在代码运行的时候(Runtime)去进行代理。比如我们比较常见的代理View.OnClickListener、Window.Callback、View.AccessibilityDelegate等方案均属于这种方式。这几种方案,我们也会在后面一一进行介绍。
不同的方案,其处理能力和运行效率各不相同,同时对应用程序的侵入程度以及对应用程序的整体性能的影响也各不相同。从总体上来说,静态代理明显优于动态代理,这是因为静态代理的“动作”是在应用程序的编译阶段处理的,不会对应用程序的整体性能有太大的影响,而动态代理的“动作”是在应用程序运行阶段发生的(也即Runtime),所以会对应用程序的整体性能有一定的影响。
·兼容性
随着Android生态系统的快速发展,不管是Android系统本身,还是与Android应用程序开发相关的组件和技术,都在飞速发展和快速迭代,从而也给我们研发全埋点方案带来一定的难度。比如不同的Android应用程序可以有不同的开发语言(Java、Kotlin)、不同的Java版本(Java7、Java8)、不同的开发IDE(eclipse、Android Studio),更有不同的开发方式(原生开发、H5、混合开发),使用不同的第三方开发框架(React Native、APICloud、Weex)、不同的Gradle版本,以及Lambda、D8、Instant Run、DataBinding、Fragment等新技术的出现,都会给全埋点带来很多兼容性方面的问题。
·扩展性
随着业务的快速发展和对数据分析需求的不断提高,对使用全埋点进行数据采集,也提出了更高的要求。一方面要求可以全部自动采集(采集的范围),同时又要求能有更精细化的采集控制粒度(采集可以自定义)。比如,如何给某个控件添加自定义属性?如果不想采集某个控件的点击事件应该如何控制?如果不想采集某种控件类型(ImageView)的点击事件又该如何处理?如果某个页面(Activity)上所有控件的点击事件都不想采集又该如何处理等。
任何一种全埋点的技术方案,都有优点和缺点,没有一种普适的完美解决方案。我们只需要针对不同的应用场景,选择最合适的数据采集方案即可。能满足实际数据采集需求的方案,才是最优的方案。