将老项目的Gradle升级到3.0引发的惨案

记一次诡异的bug

Posted by lx8421bcd on December 4, 2018

经过

上个月公司的应用开始了页面改版,负责需求的同学在一个嵌套滑动的交互效果上使用了anroid-support组件,一直以来公司应用的compileSdkVersion都是25,gradle版本是2.3,因为更新gradle需要重新测试tinker,所以一直没折腾。
这位同学上了support库测试的时候发现处理滑动冲突时有bug,查了一下返现新版support库修复了,然后给升到了28,发现报了一堆红,然后把compileSdkVerion升到了28,然后报错,然后把gradle版本升到了3.0.1,然后butterknife报错了,查了一下,又把JavaVersion配置从1.7改到了1.8。 好了,没有报错了,build也过去了,打包测试没问题,发布吧~

……

第二天就有人反馈我们应用新版本打不开了,与此同时我被崩溃监测平台刷爆了,而且问题很严重…… bugtags_stat
看到这崩溃信息我内心也是崩溃的,Application初始化崩溃,次数还这么高,怕是出大事故了。
然而这崩溃信息内涵却十分丰富,这么高的崩溃次数,影响机型却这么少,用户数也很少。

看崩溃堆栈信息,居然崩在腾讯云SDK内部……
tencent_sdk
这就很诡异了,如果是腾讯云SDK有问题,还是ArrayIndexOutOfBounds这么低级的错误,为什么以前版本不崩?肯定是这版本改了什么导致的,那么最可疑的就是compileSdkVersion,gradleVersion,JavaVersion几个参数了。然而这几个都不好隔离开测,改一个就得全部改,得再找其它信息。

看崩溃统计信息,所有崩溃机型系统版本全部是 Android 5.1
然后我找了几台5.1的测试机,只有一台魅族MX5能够复现,这就更诡异了……

组合堆栈信息 + Android 5.1看看会有什么结果,然后我找到了这篇 ArrayIndexOutOfBoundsException at okio.Base64.encode(Base64.java:137),从issue的讨论来看,崩溃信息极其相似,我自己也再看了一下统计信息,果然,崩溃的全部都是联发科……
问题是由于3.0版本的D8编译器生成的代码在部分 联发科 + Android5.1 的机型上产生了奇妙的反应,解决办法是将gradle升级到3.1以上,于是我将Gradle升级到最新的3.2.1,修改了一些配置。打包在魅族MX5上测试,通过。

总结

  1. 老项目升级Gradle需要特别注意D8编译器相关的配置,要升级Gradle直接升级到最新
  2. 除非必须,或者时间充足,不然轻易不要修改项目基础配置,引用库版本,修改之后一定要经过充分测试
  3. 辣鸡MTK 😂

后记

在我升级gradle到3.2.1交付测试通过发版之后,有用户反馈新版本在Android 4.4上打不开了,这次我连崩溃记录都没看到,于是自己找了一台4.4的手机试了一下……

必现!(当场颤抖 😱

这次的崩溃比上次更厉害,tinker初始化时就崩了,Application初始化都没执行完,崩溃统计SDK也没初始化所以收集不到统计数据。tinker报错:ClassNotFoundException: XXXApplictionLike。查询了一下issue,Android Studio 3.2,Gradle 4.6,编译异常,使用新版gradle由于分包问题,需要添加dex_keep配置,添加之后问题解决。

以上就是由于升级Gradle导致3天发了3个版本的惨案,教训可谓深刻:

  1. 不要随便升级基础配置
  2. 充分测试,充分测试,充分测试!除非minSdkVersion=21,不然在修改基础配置,引入SDK,修改SDK等操作时必须测试4.4以下!