当前位置:网站首页>大厂面试必备技能,2022Android不死我不倒
大厂面试必备技能,2022Android不死我不倒
2022-07-05 19:04:00 【InfoQ】
先上一份面试资料目录
业内情况
无痕埋点
可视化埋点
阶段一:无痕埋点
无痕埋点技术实现
页面ID规则
- Activity,ID 规则为
ActivityClassName|额外参数
- Fragment,ID 规则为
ActivityClassName[FragmentClassName]|额外参数
页面PV、UV
onResume()onResume()setUserVisibleHint(boolean isVisibleToUser)onHiddenChanged(boolean hidden)- Activity

- Fragment

控件ID规则

FrameLayout[0]/LinearLayout[1]/Button[0]


控件ID的优化

FrameLayout[0]/LinearLayout[2]/Button[0]- 优化1:将兄弟节点中的位置,变成相同类型控件的位置。优化后的控件路径为:
FrameLayout[0]/LinearLayout[1]/Button[0],即使在插入 FrameLayout 后,其路径仍旧不变,相较之前会更加稳定一些。但如果插入的是 LinearLayout,或者整个页面的 UI 进行了重构,控件路径依旧会发生改变。
- 优化2:因为不同的系统版本或手机厂商,会对页面的根 View 做一定的处理,所以我们需要屏蔽掉这种情况,对于我们而言,我们只关心我们自定义的那部分布局,即通过 setContentView 传入的布局。我们可以通过判断控件 ID 是否等于
android.R.id.content来获取我们自定义的布局的根 View,并将其作为我们控件路径的起点。
- 优化3:在 Android 中,除了
R.id和控件路径之外,还有一个比较常用的可以作为控件 ID 的特征信息,那就是开发者写在布局文件中,关联控件的 Resource ID。Resource ID 是开发者自己定义的关联 View 的标识,在一个页面当中,理论上是唯一的(为什么说是理论上,因为还是存在有多个相同 Resource ID 的情况,比如动态的 add 多个 layout,且包含了相同的 Resource ID,但这种情况非常少),并且在页面的重构过程中,Resource ID 也一般不会修改,因此用 Resource ID 来作为控件 ID 是非常合适的。但并不是所有的控件都有 Resource ID,我们可以先尝试去获取这个 ID,假如 Resource ID 存在,则使用 Resource ID 来作为控件 ID,假如 Resource ID 不存在,则降级使用控件路径作为控件 ID。核心代码如下:

控件的点击、长按指标
onClick(View v)onLongClick(View v)- 点击

- 长按

代码插桩
Javassist

gradle 插件


- 先根据类名得到
CtClass对象
- 再根据我们想要寻找的切入点,页面就找
onResume()方法,控件就找onClick(View view)方法
- 然后根据方法名和参数类型,得到
CtMethod对象
- 调用
CtMethod对象的编辑方法体的 API,在原始方法体之前插入就调用insertBefore,之后就调用insertAfter,传入需要插入的代码块
- 调用
CtClass的writeFile()方法,保存这次编辑
阶段二:可视化管理后台


上报控件信息
- 可被点击或长按
- 在当前界面可见


- 判断 View 本身可见性属性
- View 本身可见性属性比较容易判断,我们只需要判断
View.isShown()并且View.getVisibility() == View.VISIBLE即可。
- 判断 View 所处的位置是否在当前屏幕内
- 一个 Activity 加载了多 Fragment 的情况下,可能会出现控件本身可见性属性达标,但实际并不在屏幕内的情况。这种情况我们根据
View.getLocationOnScreen(int[] outLocation),然后通过判断outLocation[0],是否大于等于 0 且小于等于屏幕宽度,就能判断控件是否在当前屏幕内。
- 判断控件是否被其他控件完全遮挡
- 遍历所有与该控件有关联的控件(同层控件、父控件、父控件的同层控件等),通过
View.getGlobalVisibleRect(Rect viewRect)来得到控件所对应的 Rect 信息,然后通过Rect.contains(Rect r)来判断两个控件对应的 Rect 是否完全包含即可。
最后



边栏推荐
- 5. Data access - entityframework integration
- 机器学习基础(三)——KNN/朴素贝叶斯/交叉验证/网格搜索
- Debezium系列之:postgresql从偏移量加载正确的最后一次提交 LSN
- C# 语言的基本语法结构
- JAD的安装、配置及集成IDEA
- 中国银河证券开户安全吗 证券开户
- Teach you to deal with JS reverse picture camouflage hand in hand
- The basic grammatical structure of C language
- 1亿单身男女撑起一个IPO,估值130亿
- 2022最新大厂Android面试真题解析,Android开发必会技术
猜你喜欢

测试外包公司怎么样?

HiEngine:可媲美本地的云原生内存数据库引擎

UWB超宽带定位技术,实时厘米级高精度定位应用,超宽带传输技术

Debezium系列之:记录mariadb数据库删除多张临时表debezium解析到的消息以及解决方法

Applet modification style (placeholder, checkbox style)

Thoroughly understand why network i/o is blocked?

Ten years at sea: old and new relay, dark horse rising

面试官:Redis 过期删除策略和内存淘汰策略有什么区别?

Fuzor 2020軟件安裝包下載及安裝教程

在线协作产品哪家强?微软 Loop 、Notion、FlowUs
随机推荐
After the company went bankrupt, the blackstones came
PHP利用ueditor实现上传图片添加水印
面试官:Redis 过期删除策略和内存淘汰策略有什么区别?
Common interview questions in Android, 2022 golden nine silver ten Android factory interview questions hit
毫米波雷达人体感应器,智能感知静止存在,人体存在检测应用
MMO項目學習一:預熱
Django uses mysqlclient service to connect and write to the database
HAC集群修改管理员用户密码
Tupu software digital twin smart wind power system
The era of Web3.0 is coming. See how Tianyi cloud storage resources revitalize the system to enable new infrastructure (Part 2)
Why can't Bi software do correlation analysis? Take you to analyze
How MySQL queries and modifies JSON data
Oracle故障处理:Ora-10873:file * needs to be either taken out of backup or media recovered
Technology sharing | common interface protocol analysis
HiEngine:可媲美本地的云原生内存数据库引擎
强化学习-学习笔记4 | Actor-Critic
Analysis of postman core functions - parameterization and test report
Debezium系列之:修改源码支持drop foreign key if exists fk
JAD installation, configuration and integration idea
测试外包公司怎么样?