项目中多次操作SharedPreferences导致ANR场景的解决

蚀纹阈值
• 阅读 2052

项目背景:

随着时代的进步,移动端广告的投放变得越来越多样化,为了接近市场,不少公司自己研发了SDK去收集用户的一些信息以及行为用于分析,根据分析结果使用自定义广告(自定义View)的方式继续向用户进行展示,以提高展示率和点击率。
目前关于广告商方面的选择,国内的广告变现普遍较低,首选应该是接入谷歌广告。随着业务的发展,在一段时间后,公司开始转变成广告接收方,并靠自己的SDK来进行广告的投放,以及优化。
以定位来获取广告的方式为例:
· 首先利用用户的定位等权限来获取经纬度

项目中多次操作SharedPreferences导致ANR场景的解决
· 将经纬度上传至国内某定位SDK,获取具体信息。
项目中多次操作SharedPreferences导致ANR场景的解决
· 最后根据定位信息来获取广告并预加载为广告展示做准备。
项目中多次操作SharedPreferences导致ANR场景的解决

所遇到的挑战:

在项目功能完成后准备上架前,会对项目进行一系列的测试,但是ANR问题在测试过程中很难完成复现,在使用多个机型测试的过程中几乎没有ANR问题的记录。但是在用户的实际使用过程中,由于Android碎片化的严重,加上用户的一些操作的习惯等,会导致出现ANR的问题。面对一些大型的厂家,ANR出现时会弹窗引导用户关闭软件,会导致使用体验不好,造成用户的流失。

解决问题的步骤:
在项目一个多月的异常收集中,出现过几次ANR的问题。
· 分析异常收集中ANR日志将问题锁定在SharedPreferences 上,排查过程比较麻烦,在锁定了问题后,开始对问题进行分析。
· 查看Android文档:在项目中,团队使用SharedPreferences读写配置文件,均采用了官方的推荐做法,调用apply来提交,调用这个方法时,先写入内存中,再将任务加入队列中,会在异步线程中做落盘的操作,这个操作理论上来说是没有问题的,也是google官方推荐的做法。
· 阅读源码:
项目中多次操作SharedPreferences导致ANR场景的解决

在此过程中发现谷歌官方注释:
If another editor on this SharedPreferences does a regular commit() while a apply() is still outstanding, the commit() will block until all async commits are completed as well as the commit itself.
翻译:如果SharedPreferences上的另一个编辑器执行常规的commit(),而apply()仍然未完成,则commit()将阻塞,直到所有异步提交以及提交本身都完成。

· 锁定问题:主线程调用了 QueuedWork.waitToFinish(),没有待执行的任务,直接执行 finisher,进行阻塞等待, 直到写入文件成功后恢复执行, 这时候如果等待时间过长, 在一些市面上性能差的中低端机型上就会很容易出现ANR。 (8.0以下)
问题的解决
当时的优化:

  1. 减小sp对应的文件的大小,按照分类去读写对应的sp文件。
  2. sp的读写轻量的、小的配置信息,将类似JSON的数据交给其他方式保存。
  3. 当需要多次调用Put系列方法,当逻辑确认不需要立即读取时,在最后一次调用commit或apply即可。

最近朋友推了一篇字节的博客(以下文字以及图片来源于字节今日头条团队)。

· 思路:如果能让sPendingWorkFinishers.poll()返回为null,则这里的等待行为直接就跳过去了,sPendingWorkFinishers是个ConcurrentLinkedQueue集合,可以直接动态代理这个集合,覆写poll方法,让其永远返回null,这个时候UI永远不会等待子线程写入文件完毕,事实证明这种方式简单有效。
项目中多次操作SharedPreferences导致ANR场景的解决

· 针对这种写入等待的ANR问题,还有一种就是全局替换写入方式,通过插桩的方式,替换所有的API实现,采用其他的存储方式,这种方式修复成本和风险较大,但是后期可以随机的替换存储方式,使用比较灵活。

友盟平台相关SDK初体验:
由于ANR的比较难复现,于是写一个方法,反复对SharedPreferences进行操作,以达到类似情况的复现。
项目中多次操作SharedPreferences导致ANR场景的解决

出现问题,通过友盟U-APM平台定位:

项目中多次操作SharedPreferences导致ANR场景的解决

找到问题后,进行文中思路的操作即可。

总结
在情景中,由于Android太过碎片化,又不得直接舍弃低版本用户,采用接入类似友盟U-APM平台的方式去更快的解决问题是必不可少的。但对于一些小型手机的低版本可能还是会出现ANR的问题,针对类似收集用户行为的情景,可采取进行多种方式去进行收集,例如对于低版本的系统,降低对收集数据的完整性等。

作者:计蒙不吃鱼

点赞
收藏
评论区
推荐文章
blmius blmius
4年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Oracle 分组与拼接字符串同时使用
SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(
Wesley13 Wesley13
4年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
待兔 待兔
1年前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
4年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
今日头条广告代理商怎么找?如何分辨真假?
随着移动互联网营销时代的发展,很多广告主都想借助今日头条平台的发展来推广自己的产品及服务,因为今日头条平台到目前为止已拥有超过7亿的用户了,今日头条平台对于用户来说,就像逛淘宝和天猫一样,每一天的搜索动作都是必不可少的,而且它比其他平台多了一个自动分析、整合、推送相关产品的功能,这既不会给用户带来干扰,也可以节省广告主的广告投放资金。然而,广告主在投放广告这
常见五大广告投放问题!从问题背后总结规律!
做电商广告投放,总是广告投放的多,收到的回报少。广告投放的学问是长期学习的过程,需要日积月累累计起来的经验,今天就收集了几个问题,来给大家解答一下,五大关于。1.转化少点击少展现没问题,就是创意排名有问题吧?答:思路没错,点击量少自然转化量也不会提升,而点击量展现量点击率,展现量正常点击量低,主要是点击率的问题,影响点击率问题的环节就是广告创意。做信息流投
Easter79 Easter79
4年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
4年前
ThinkPHP 根据关联数据查询 hasWhere 的使用实例
很多时候,模型关联后需要根据关联的模型做查询。场景:广告表(ad),广告类型表(ad\_type),现在需要筛选出广告类型表中id字段为1且广告表中status为1的列表先看关联的设置部分 publicfunctionadType(){return$thisbelongsTo('A
Python进阶者 Python进阶者
2年前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
京东广告算法架构体系建设--在线模型系统分布式异构计算演变 | 京东零售广告技术团队
一、现状介绍算法策略在广告行业中起着重要的作用,它可以帮助广告主和广告平台更好地理解用户行为和兴趣,从而优化广告投放策略,提高广告点击率和转化率。模型系统作为承载算法策略的载体,目前承载搜索、推荐、首焦、站外等众多广告业务和全链路的深度学习建模,是广告算法