点击上方蓝字关注我们
3、页面切换事件/APP启动/结束事件
页面切换浏览就是指用户在不同的Activity或者Fragment组件中进行切换,对于这两个组件都有其对应的生命周期监听器,对于Fragment可以有属于自己的栈管理器,如何监听到这些组件的展示回调是实现无埋点代码插入时机的关键。
Activity生命周期的监听大家首先想到的就是在BaseActivity中的OnResume生命周期中拿到页面ID做埋点逻辑,让所有业务层Activity都继承这个BaseActivity,这种方案是可行的,最大的痛点就是无法控制让三方库中的Activity组件库也继承BaseActivity。而且这种方案违背了“纯净”原则,入侵了业务代码。本方案采用Application.ActivityLifecycleCallbacks形式对各Activity组件进行监听,它是Android 4.0开始提供,通过注册Application便可收到所有Activity的所有生命周期回调,代码如下,这里还能通过计算Activity的数量实现监听APP启动/结束事件(代码如下所示):
Fragment生命周期的监听也可以模仿这种方式,通过registerFragmentLifecycleCallbacks注册FragmentLifecycleCallbacks从而实现各Fragment生命周期的回调,这种形式的痛点在于使用add来添加Fragment时,FragmentLifecycleCallbacks会收不到系统的生命周期回调函数。本方案采用的另外一种形式则是监听回退栈的变化,在Application.ActivityLifecycleCallbacks的onActivityCreated函数中先对其内部的各大Activity的Fragment回退栈注册监听器(代码如下所示)。
而后重写FragmentManager.OnBackStackChangedListener,做逻辑埋点。
为了便于前端运营人员更易理解页面ID含义,可使用一些手段上报页面ID语义化翻译给后端做筛选处理。可选方案有手动建立ID翻译映射关系表格上报;页面切换埋点采集时自动上报。这两种方案都需要Android开发者为对应的页面起名字,前者需要前后端规定建表格式规则,手动做映射复制工程,流程自动化能力差,而后者对于后端具备明显优势,因为不用再次对表格中的数据进行映射和导入处理流程。本方案采用第二种页面注解语义化采集方案,在Android项目代码Activity、Fragment组件类上标记注解中文名即可(代码如下所示)。
方案一:同样采用Application.ActivityLifecycleCallbacks形式对各Activity组件进行监听,在onActivityResumed回调方法中通过activity.findViewById(R.id.content),就可以拿到整个布局中的所有View(通过判断是否为ViewGroup类型进行遍历),找到目标View后进行埋点代码代理插入操作。首先通过反射的手段获取到点击事件对象原生业务逻辑,进行判断若类型是原生的View.setOnClickListener则进行自定义包装成WrapperOnClickListener,在执行原生OnClick之后插入埋点逻辑。这种方案的缺点是反射效率低,对APP本体性能有影响,再者伴有兼容性问题,反射取点击对象操作时对API有版本要求。
方案二:Android打包流程中,在打包成.dex文件之前可利用Transform API拿到.class文件,Google允许使用这套API以Gradle插件形式,实现对打包成.dex 文件之前的编译过程中操作字节码文件.class,然后再利用ASM字节码操作框架对其进行加载解析,它能动态生成类或者增强既有类的功能,对于点击事件操作事件,即找到特定的clickListener方法对其进行埋点代码插入修改,这就是所谓的“字节码插桩”,保存修改后可顺利通过编译规则打包成应用程序并运行。因为是在编译期进行代码插入,对于程序运行时的性能是没有影响的,并且不受API版本等兼容性问题影响,流程如图:
第一步:定义出要使用ASM插入到字节码文件中的埋点代码。
第二步:新建GradlePlugin,并新建一个Transform类,其中在transform方法中要实现遍历目录中的每一个.class文件,修改后并保存。
第三步:遍历到.class文件后,利用ASM中的ClassVisitor进行修改符合特定条件的方法。
可见组件操作事件代码插桩方案二,针对Dialog字节码文件识别条件如下,过程不再赘述。
6、崩溃事件上报事件
崩溃信息对于Android开发者跟踪错误日志是尤为必要的,譬如可了解分析到线上未适配的新机型,整理崩溃CASE产生条件等,有助于提升完善产品质量。本方案采用Crash拦截立即上报的方式,保证服务端第一时间拿到最新的Crash信息,若上报未成功,则下次开启APP后轮训上报时机重试。
为使Android开发者更高效的接入无埋点方案,根据上述埋点策略,可将Gradle插件及埋点代码抽象出来封装成SDK。本SDK具备了日志采集、缓存、上报能力,流程如下图所示,采集到的日志先会放到内存缓存,当轮询时间已到便会触发上报网络任务,若上传成功则会自动删除数据,若失败则将数据存入外存,等待下一次上报时机读取内/外存再次重试。
得益于高度规范化埋点规则,数据采集、处理及可视化均已告别低效的手动流程,统一的采集服务,流批一体化清洗流程和多维度分析看板使得客户端埋点接入即可实时追踪用户行为,h+1获悉新增App分析数据。
技术架构
◇ 行为追踪,即获悉谁(who),何时(when),何地(where),做了什么(what)以及如果做到(how)。
◇ 趋势分析,通过个体的行为统计,获悉各用户群体行为趋势,以辅助或佐证决策。
针对上述两种分析场景,对数据处理要求也不尽相同,行为追踪追求数据时效性,如实时推荐,用户操作过程中,即刻通过行为样本分析进行个性化推荐。而趋势分析,则寻求通过复杂计算逻辑挖掘数据最为深层的价值。所以针对不同的业务诉求在数据处理上也采用了Lambda流批一体的方式:实时加工+离线分析。
流批一体:通过离线补偿方式,确保实时数据最终一致性,准确性。
◇ 通用看板:根据通用埋点信息,数据团队产出了用户行为跟踪,页面分析,用户画像看板,通过多维度关联下钻方式,满足个体行为分析,趋势分析,用户群体分析等场景诉求。
◇ 个性分析:针对各业务个性化诉求,可通过在线查询集群结合报表系统,以拖拉拽方式快速由底层数据进行可视化分析。
无埋点方案通过与大数据后端规定的事件约束,制定了通用化埋点事件分类,支持了移动客户端项目中无埋点日志采集上报能力,并且将其抽象包装成库组件,使开发者高效接入,真正做到了无业务代码入侵式埋点并自动完成采集、缓存、上报日志流程。它的意义不仅为科技公司打造了属于自己的无埋点生态环境,更在于便于监控和洞悉产品运营状态及使用特征,从而辅助为客户优化打造更高质量的产品迭代。
THE END