当前位置:网站首页>大厂面试必备技能,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 是否完全包含即可。
最后
边栏推荐
- 面试官:Redis 过期删除策略和内存淘汰策略有什么区别?
- 毫米波雷达人体感应器,智能感知静止存在,人体存在检测应用
- C# 语言的高级应用
- PG基础篇--逻辑结构管理(用户及权限管理)
- Golang through pointer for Range implements the change of the value of the element in the slice
- 【FAQ】华为帐号服务报错 907135701的常见原因总结和解决方法
- Applet modification style (placeholder, checkbox style)
- golang通过指针for...range实现切片中元素的值的更改
- Tupu software digital twin | visual management system based on BIM Technology
- Debezium系列之:修改源码支持unix_timestamp() as DEFAULT value
猜你喜欢
Oracle故障处理:Ora-10873:file * needs to be either taken out of backup or media recovered
Talking about fake demand from takeout order
2022 the latest big company Android interview real problem analysis, Android development will be able to technology
数据库 逻辑处理功能
Django uses mysqlclient service to connect and write to the database
How to quickly advance automated testing? Listen to the personal feelings of the three bat test engineers
JMeter 常用的几种断言方法,你会了吗?
Tutoriel de téléchargement et d'installation du progiciel fuzor 2020
5. Data access - entityframework integration
Interviewer: what is the difference between redis expiration deletion strategy and memory obsolescence strategy?
随机推荐
【FAQ】华为帐号服务报错 907135701的常见原因总结和解决方法
2022年5月腾讯云开发者社区视频月度榜单公布
Technology sharing | common interface protocol analysis
Optimization of middle alignment of loading style of device player in easycvr electronic map
Word finds red text word finds color font word finds highlighted formatted text
[performance test] jmeter+grafana+influxdb deployment practice
vagrant2.2.6支持virtualbox6.1版本
2022 the latest big company Android interview real problem analysis, Android development will be able to technology
自动化测试的好处
毫米波雷达人体感应器,智能感知静止存在,人体存在检测应用
cf:B. Almost Ternary Matrix【对称 + 找规律 + 构造 + 我是构造垃圾】
cf:B. Almost Ternary Matrix【對稱 + 找規律 + 構造 + 我是構造垃圾】
Golang through pointer for Range implements the change of the value of the element in the slice
如何实现游戏中的在线计时器和离线计时器
MMO项目学习一:预热
Notion 类生产力工具如何选择?Notion 、FlowUs 、Wolai 对比评测
块编辑器如何选择?印象笔记 Verse、Notion、FlowUs
Interviewer: what is the difference between redis expiration deletion strategy and memory obsolescence strategy?
MySQL中字段类型为longtext的值导出后显示二进制串方式
R language uses lubridate package to process date and time data