一个关于PagView的native crash 排查和解决方案

550 阅读3分钟

一、背景

8.46.0.0版本上线后辣妈用户反馈进入app后就闪退,无具体日志,都是系统堆栈;

二、排查过程与闪退原因

1、查看bugly,友盟均无日志

2、怀疑新上线的快手SDK和穿山甲SDK,确实有一部分用户闪退是因为这个;但依然有用户反馈闪退,大部分都是辣妈用户

3、测试拿到复现率较高的设备,输出如下日志:

日志1:

image.png

日志2:

image.png

 日志3:

![]( "美柚-Android > (已解决)8.46.0.0版本上线后辣妈用户反馈进入app后就闪退,无日志 > image2022-9-21_16-24-52.png")

image.png

从日志1可以看出:app闪退问题在于 UI binder dead,应该是渲染线程死亡,导致crash;

从日志2可以看出:app闪退原因在于,线程消耗殆尽;

从日志3可以看出:app在启动后,执行了653次解码动作,可能是引发问题2的关键;

排查辣妈身份8.46.0.0版本的需求,发现8.46.0.0版本上线了将gif更换为pag动图的需求,怀疑是pagview引起的,于是我们尝试hook掉pagview的display方法,发现不会闪退,至此,可以定位是这个改动引起的;

4、进一步分析:

其他业务的pag动图不会闪退,为什么辣妈身份下更换pag动图就会闪退呢?有两种可能,1、pag素材太复杂了;2、同时播放的pag太多了或者调用太频繁了;

4.1 我们尝试将pag换成简单的pag图,发现公司的内测设备不再闪退;然后将此pag图片上线;发现线上依然有用户反馈。所以可以得出结论1:pag素材层次复杂度可能影响某些设备,因为其可能需要大量的解码线程,消耗大量资源,进而造成闪退;

4.2 在4.1的基础上,用户的设备依然存在闪退,我们在hook pagview display的过程中,发现进入辣妈首页,调用了20次以上的pagview播放,可以断定,进入首页后,一次性加载了大量pag动图,并进行了播放,

而这次的宝宝动图,图层可能高达100以上,所以再大批量加载动图,两者结合消耗了大量的线程资源,最终导致闪退;所以可以得出结论2:pag素材层次复杂度过高+一次性加载过多的pagview并进行播放,会消耗大量资源,进而造成闪退

三、解决方案

1、回退代码为gif播放

2、一次加载过多的问题,是因为8.46.0.0版本开发将懒加载机制移除了,导致了一次性加载过多动画的问题,此问题已在8.46.0.1版本修复;

3、底层框架针对使用PagView播放在测试环境加入toast警示文案,避免业务频繁调用。 

四、PagView稳定性结论

PagView依然可用,但是需要注意素材的层次和界面加载数量;

其实gif或者lottie再播放较为复杂的动画时候也会存在在这问题,只不过闪退的原因会变成OOM,而PagView由于依赖了硬件加速,所以闪退原因会变成系统相关的闪退;