神策 Android 全埋点插件介绍 | 数据采集

优采云 发布时间: 2022-06-09 12:41

  神策 Android 全埋点插件介绍 | 数据采集

  

  

  一、前言

  埋点是数据采集领域的一个术语,它是指针对特定用户行为或事件进行捕获、处理、上报的过程。埋点技术实质就是在合适的时机去采集行为数据,同时获取必要的上下文信息,最后将行为数据上报到指定的服务端。埋点获取到的业务数据可以为产品后续的迭代方向和评判营销价值提供有力、可靠的数据支撑。

  常见的埋点方式主要包括全埋点和代码埋点(又称自定义埋点)。其中,全埋点可以满足 UV、PV、点击量等常见指标统计的需求,适用于以较小的埋点代价收集尽可能多的用户行为数据的场景。下面将首先针对神策 Android SDK 全埋点功能作简要的介绍,然后重点讲解 Android 全埋点插件的作用和实现原理。二、全埋点介绍

  2.1基本概念全埋点,也叫无埋点、*敏*感*词*埋点、无痕埋点、自动埋点等。全埋点,是指无需应用程序开发工程师写代码或者只写少量的代码,即可预先自动收集用户的所有或者绝大部分的行为数据,然后再根据实际的业务分析需求从中筛选出所需行为数据并进行分析。神策 Android SDK 全埋点采集的事件目前包括以下四种(事件名称前面的 $ 符号,是指该事件是预置事件):

  • $AppStart 事件

  是指应用程序启动事件,包括冷启动和热启动场景。冷启动是指在系统中没有该应用的进程时启动应用程序,热启动是指在系统中已有该进程时启动应用程序,热启动也可以理解为从后台打开 App。

  • $AppEnd 事件

  是指应用程序退出事件,常见的退出场景包括应用程序的正常退出、进入后台、应用程序被强杀、应用程序崩溃等场景。这里需要注意的是神策 Android SDK 为了应对多进程、强杀等场景,加入了 30 秒的 session 机制,即用户退出 App 到后台 30 秒的时候才会触发退出事件。

  • $AppViewScreen 事件

  是指应用程序页面浏览事件,对于 Android 应用程序来说,就是指切换 Activity 或 Fragment。

  • $AppClick 事件

  是指应用程序控件(View)点击事件,例如:点击 Button、ImageView 等。2.2实现原理实现 App 启动、退出和页面浏览(Activity)的全埋点较为简单,事件的采集围绕 Activity 生命周期展开即可。Android 官方在 Android 4.0 及以上版本提供 Application.ActivityLifecucleCallbacks 接口,之后再调用 Application.registerActivityLifecycleCallbacks 方法并传入 Application.ActivityLifecycleCallbacks 接口的实现类,就可以在实现类中获取到之后所有 Activity 生命周期的回调。这样,我们只需要做一些简单判断就可以实现以上全埋点事件的采集。实现 App 浏览页面(Fragment)和点击的全埋点则要复杂的多,虽然这两个事件要埋点的位置很清楚(例如:Button 的 OnClickListener.onClick 方法触发就可以视为 Button 的点击),但是并没有一个像 Application.ActivityLifecycleCallbacks 一样全局托管的接口。因此,我们需要利用一些技术在原处理逻辑中“插入”我们想要的埋点代码,从而实现自动埋点的效果。神策的 Android 全埋点插件正是为了解决这个问题而推出的。三、全埋点插件的实现原理

  想要自动在我们规定的位置插入特定的埋点代码,需要先了解 Android 的构建流程,如图 3-1 所示:

  

  图 3-1 Android Apk 构建流程图(图片来源于 Android 开发者官网)

  通过上图可以知道,Compilers 会将源码转化成 DEX 文件,其他内容转化成编译后的资源。实际上,Compilers 到 DEX 文件这一步会先将源码编译成字节码文件,再通过 dex 命令将字节码文件处理成 classes.dex。而我们需要做的就是:在转化成 dex 之前对字节码文件做处理,遍历所有的字节码文件并在特定的逻辑处进行插码。进一步细化思路可以分为两个步骤:

  1.在转化成 dex 之前获取到全量、可处理的字节码文件流;

  2.识别字节码文件中的特定逻辑并插入自定义的埋点代码。

  注意:对于上述的第二步,如果你写过 Xposed 插件或者了解过 Spring 框架原理的话就会觉得非常熟悉,这里使用到了面向切面编程的思想,即 AOP。按照 AOP 的思想,我们可以把要插入代码的地方抽象成切入点,然后在切入点处添加埋点代码就可以了。神策在实现这个功能的时候用到了以下关键技术:

  Gradle 插件:Gradle 是一个非常优秀的项目构建工具,它的 DSL(领域特定语言)基于 Groovy 实现。Gradle 构建的大部分功能通过插件的方式来实现,并且支持自定义 Gradle 插件。把插件应用到项目中,插件会扩展项目的功能,帮助你在项目的构建过程中做很多事情,例如:测试、编译、打包等;

  Transform API:是一组封装好的类,通过 Transform API 允许第三方以插件(plugin)的形式,在 Android 应用程序打包成 .dex 文件之前的编译过程中操作字节码文件;

  ASM:是一个通用的 Java 字节码操纵框架,它能被用来动态生成类或者增强既有类的功能。

  3.1Transform APIGoogle 从 Android Gradle 1.5.0 开始,提供了 Transform API,允许第三方插件在 Android App 打包成 .dex 文件之前的编译过程中操作字节码文件。我们只要实现一套 Transform,遍历字节码文件的所有方法之后进行修改,最终替换原文件即可达到插入代码的目的。

  我们先了解一下 Transform 的两个概念:

  TransformInput:是指输入文件的抽象,它包含 DirectoryInput 集合(代表以源码方式参与项目编译的所有目录结构及其目录下的源码文件)与 JarInput 集合(以 jar 包方式参与项目编译的所有本地 jar 包和远程 jar 包)两部分;

  TransformOutputProvider:是指 Transform 的输出,通过它可以获取输出路径。

  下面我们再了解一下 Transform 类的定义,作为一个抽象类它主要包含以下的部分: <p>class Transform {... public abstract Set getInputTypes(); public abstract Set

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线