抬头仰望星空,是否能发现自己的渺小。

伪斜杠青年

人们总是混淆了欲望和理想

java.lang.NoClassDefFoundError: Failed resolution of:$ExternalSyntheticLambda0;

背景:活久见的一起 kotlin 与 java 混用线上崩溃特例,可以确定为非混淆导致/空指针等崩溃。

影响机型:Android 5.1.1 、6.0 的 vivo、oppo、华为等老旧机型。

最终解决办法:将 kotlin 部分用 java 重写。

详情:某一天产品有一个需求,需求涉及的模块是以前的旧代码,架构为 MVP ,使用了 Rxjava2 ,前阵子同事将 Rxjava 升级到了 Rxjava3,我在数据层加了一些逻辑,使用了新操作符 zipWith,由于涉及了新接口的请求,请求返回的数据接口涉及多层嵌套,而我习惯了 kotlin 于是讨厌这种写法:

//伪代码
if(response !=null && response.Page!=null && response.Page.getItems()!=null)

相对于 kotlin 就是:

response?.Page?.getItems()?:emptyList()

于是我兴高采烈的就提交了代码,测试用公司的测试机测试过后也没发现问题,就如往常一样上线了。

第二周,第一天发现听云崩溃,看到几个零星崩溃,以为是有人在用低版本机器搞我们的应用,所以我忽略了,第二天,有一个客户反馈,说应用启动就崩溃,那时候我才注意到原来是真有用户在用 Android 6.0,而第三天也有一个 Android 5.1.1 的客户反馈崩溃。

于是我就开始修,我排查问题定位代码,最后定位到我那个从 zipWith 中独立出来的实现了 BiFunction 的 kt 类。至于 ExternalSyntheticLambda0 其实就是 kotlin 中的闭包生成的一些匿名类,也就是 ()->Unit 这种类型。

在我各种尝试后,比如用 java 去实现 BiFunction,将 apply 方法的内容用 kotlin 去实现,运行上云测,失败了,云测的安装什么都很慢,于是在后续几次尝试没成功后,决定彻底用 java 重写,测试没问题后就交给测试了。

这个过程中我唯一没能验证的就是 kotin 的这种写法:

fun a{
  fun b(){}
  //...
  b()
}

我很怀疑是这部分代码导致的崩溃,但我发现项目里这种写法也不少,但是并没有反馈崩溃。我没去写 demo 验证,因为我感觉写了也是浪费时间,如果真有这种问题网上应该能查到,而我没找到相关问题。

于是,只能是不了了之,或许是 Rxjava3 的操作符里又做了什么转换导致,不过这东西已经过时,也就一些老代码在用,能跑就放那儿,网上也没什么人再去研究 Rxjava 了,我也不愿投入过多精力。

错误贴这儿:

java.lang.NoClassDefFoundError: Failed resolution of:Lcom.xxx.xxx.kt$ExternalSyntheticLambda0;

以后如果有谁踩坑了,知道原因了还劳烦告知下,也算是满足下好奇心,活久见呐。


本站由以下主机服务商提供服务支持:

2条评论

  • 猩猩点灯

    今天也遇到了类似的问题,非毕现,同样只要出现的设备就会一直出现这个故障。

    • Mosaic-C

      那很不幸,属于是万中选一的不幸。

发表评论