没有合适的资源?快使用搜索试试~ 我知道了~
本文基于网易乐得无埋点数据收集SDK,无埋点数据收集SDK用于向大数据平台提供全量,完整,准确的客户端数据.Android端无埋点数据收集SDK实现中涉及到比较关键的技术点有:用字节码插桩的方式实现Android端的AOP(“Hook”)唯一定位界面上任何控件的ViewIDFragment页面的合理划分自定义数据收集DSL,用于线上配置,即时收集定制的业务数据关于第一点Android端AOP的实现,之前的一篇文章AndroidAOP之字节码插桩已经做了详细的阐述。本文接着讲一下关于收集SDK内部收集逻辑的一些关键技术(即后面三点).本部分首先简要介绍一下我们的收集方案目前可以收集到哪些数据,然
资源推荐
资源详情
资源评论
Android无埋点数据收集无埋点数据收集SDK关键技术解析关键技术解析
前言
本文基于网易乐得无埋点数据收集SDK,无埋点数据收集SDK用于向大数据平台提供全量,完整,准确的客户端数
据.
Android端无埋点数据收集SDK实现中涉及到比较关键的技术点有:
用字节码插桩的方式实现Android端的AOP(“Hook”)
唯一定位界面上任何控件的ViewID
Fragment页面的合理划分
自定义数据收集DSL,用于线上配置,即时收集定制的业务数据
关于第一点Android端AOP的实现,之前的一篇文章Android AOP之字节码插桩已经做了详细的阐述。本文接着讲一下
关于收集SDK内部收集逻辑的一些关键技术(即后面三点).
一、概述
本部分首先简要介绍一下我们的收集方案目前可以收集到哪些数据,然后对于本文重点介绍的三个技术点进行概述.
1.1 SDK数据收集能力现状
目前我们的SDK进行数据收集时基本有两个能力:
通用数据全量收集
通用数据指的是与业务无关的用户行为数据,无论是电商应用还是社区应用,接入SDK后通用数据的收集上都是无差
的,这些通用数据大致有:
业务相关数据需求通过下发配置进行无埋点定制收集
除了上述通用数据,与具体业务相关的数据收集。拿网易贵金属的首页举个例子:
假使需要在用户点击上图红框区域时,把“粤贵银”这个交易品的ID(或者下方显示的指数等,只要在内存中存在的数据
都可以)一起报上来。
对于此种需求,数据收集SDK做到了无需埋点,不依赖开发周期,通过线上下发一些配置信息,即可即时进行数据收
集。具体原理第四节叙述。
1.2关键技术点概述
View的唯一标识(ID),(详见本文第二节)
当我们收集控件数据时碰到的第一个问题就是:如何把界面上的任何一个View与其他View区分开来.
比如:某个Button被点击了
我们在上报数据的时候需要把这个Button和其他所有控件(比如另一个Button,另一个ImageView等)区分开来,这样
这条上报的数据才能表示"就是那个Button被点击了一下".
这就需要为界面上的每一个控件生成一个唯一的ID. 此ID除了具有区分性,还需要用于一致性.一致性是同一个View无
论界面布局如何动态变化,或者说多次进入同一页面,此ID需要保持不变.
页面的划分,(详见本文第三节)
除了Activity有些Fragment也需要看作页面,这就要求:
在Fragment show/hide时上报相关页面事件.
页面Fragment中发生的用户交互事件也需要归于此Fragment页面,即点击某个View需要上报页面Fragment的信息
(从View中怎么获取Fragment信息?)
无需埋点轻松收集定制的业务数据,(详见本文第四节)
如前面所述,默认情况下数据收集SDK会收集全量的用户交互数据,对于定制的业务收集需求,数据收集SDK也做到
了无需代码埋点,通过线上下发一些配置进行即时收集.
二、View的唯一标识(ID)
2.1 调研
用于区分界面上每个View的ID? Android系统是否提供给了我们这个ID?
确实,Android系统提供了一个ID,view.getId()即可获得一个int型的id用于区分View,但是这个ID因为以下两个原因却并不
能满足我们的需要.
有相当一部分view是NO_ID,比如在布局文件中未指定id,或者直接在代码里面new出来view,view.getId()返回的全部
都是NO_ID
这个ID是不稳定的,由于这个ID其实就是每次编译产生的R文件中的int常量,因此同一个按钮,两个版本编译出来的
ID很可能时不一样的.
因此,我们只能自己动手构建我们的ID喽,怎么构建?答案是利用所属Page+ViewTree构建ViewID.
2.2 利用ViewTree构建ViewID
在Android的概念里,每个Window(ActivityWindow/DialogWindow/PopupWindow等)上面都生长着一棵ViewTree.而屏
幕中看到的各种控件(ImageView/Button等)都是这棵ViewTree上的节点.
有Android开发环境的同学只需要打开AndroidDeviceMonitor-dump view hierarchy 就可以看到ViewTree的模样,如下
图:
因此,我们萌生出一个想法:
利用Page+ViewTree中的位置构建ViewID.
View在ViewTree中的位置主要用两点来确定:
纵向的深度
横向的index
考虑这两个因素后,我们定义一个ViewPath:
ViewPath:当前view到ViewTree根节点的一条路径,用于在ViewTree中唯一定位当前view。路径中的每个节点包含两
部分信息,即节点View类型信息,以及节点View在兄弟中的index。
如下图,是一个简单的ViewTree模型(简单到深度只有两层,每层只有两三个控件)
按照之前给的定义,上图中控件1,2,3,4的ViewPath如下
控件1ViewPath: RootView/LinearLayout[0] index为1表示此节点是兄弟节点中第一个控件
控件4ViewPath: RootView/LinearLayout[0]/ChildView1[0]
控件2ViewPath: RootView/RelativeLayout[1]
控件3ViewPath: RootView/LinearLayout[2]
上述给出的ViewPath中,每个节点(除了首节点)有两部分内容:
LinearLayout,RelativeLayout,ChildView1等ViewType信息(节点View的类型)
“[]”内的index信息,此index指示此节点是兄弟节点的第几个
这是最初的ViewPath,用ViewPath定位view,有两点特别重要:
一致性: 同一个view的ViewPath在ViewTree的动态变化中应保持不变
区分度: 不同view的ViewPath应该不同
按照这个最初的ViewPath定义在实践中还不能在一致性和区分度上满足我们的需求,后面会对ViewPath进行优化。
2.3 ViewPath的生成
上面我们由构建ViewID的需求引出了ViewPath的定义,那么当交互事件(例如:按钮点击)发生时,我们如何生成此
控件的ViewPath?
如上一篇文章Android AOP之字节码插桩所述,当用户点击某个按钮时,我们插入OnClickListener.OnClick方法中的如
下代码将会被调用:
Monitor.onViewClick(view);
上面,入参view即为当前被点击的view,获取此view的ViewPath伪代码如下:
public static ViewPath getPath(View view) {
do {
//1. 构造ViewPath中于view对应的节点:ViewType[index]
ViewType=view.getClass().getSimpleName();
index=view在兄弟节点中的index;
ViewPath节点=ViewType[index];
}while ((view=view.getParent())instanceof View);//2. 将view指向上一级的节点
}
构造出来的ViewPath如下面例子所示:
DecorView/LinearLayout[0]/FrameLayout[0]/ActionBarOverlayLayout[0]/
ContentFrameLayout[0]/FrameLayout[0]/LinearLayout[0]/ViewPager[0]/ButtonFragment[0]/AppCompatButton[0]
2.4 ViewPath的优化
2.4.1一致性优化1
情景:
在图2-2 ViewTree模型图中,如果像下面图中所示,在控件2和3中动态插入一个FrameLayout呢?
此时按照原始ViewPath的定义,我们来看看控件3的ViewPath发生了哪些变化?
ViewTree动态变化前: RootView/LinearLayout[2]
ViewTree动态变化后: RootView/LinearLayout[3]
优化:
ViewPath节点中index的含义从“兄弟节点的第几个”优化为:“相同类型兄弟节点的第几个”
优化后,发生图2-3所示界面布局动态变化时,控件3的ViewPath变化为:
ViewTree动态变化前: RootView/LinearLayout[1] index为1表示此节点是兄弟节点中第二个LinearLayout
ViewTree动态变化后: RootView/LinearLayout[1]
剩余24页未读,继续阅读
资源评论
weixin_38696922
- 粉丝: 3
- 资源: 929
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- Java项目-基于 Java+MySql+Swing图书管管理系统(视频+源码).zip
- 施工人员吊车推出车检测28-YOLO(v5至v9)、COCO、Darknet、VOC数据集合集.rar
- ART框架自动多步推理与工具利用提升大型语言模型能力
- 大规模API调用的自反思层级代理模型AnyTool研究与应用
- Agent-as-a-Judge: 使用智能体评估代码生成任务的有效性
- 强化大型语言模型作为智能体的能力研究:引入AgentTuning方法及其应用效果评估
- 断裂检测20-YOLO(v5至v9)、COCO、CreateML、Darknet、Paligemma、TFRecord、VOC数据集合集.rar
- AgentOhana统一数据和训练流水线提高自主代理学习效果
- 房屋租赁系统源码 SpringBoot + Vue 实现全功能解析
- 基于大型语言模型的自主智能体研究综述
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功