小心Kotlin下的构造函数NoSuchMethodException

问题背景

近期开发过程中,踩了一个坑, 只在release包下稳定复现,本地debug包 没有出现问题。

1
2
3
Exception in thread "main" java.lang.NoSuchMethodException: a.x.<init>(s.x,s.e)
at java.base/java.lang.Class.getConstructor0(Class.java:3585)
at java.base/java.lang.Class.getDeclaredConstructor(Class.java:2754)

通过解混淆,定位源代码,和结合mapping文件,解包看看源代码,确实是少了目标函数

方法为什么会消失?

在 Android 开发中,通常使用 ProGuard 来进行代码混淆和压缩,以减少应用程序的代码大小和防止逆向工程, ProGuard会移除一下没有引用到的方法和字段,如果我们要通过其他方式使用,需要对ProGuard声明保留某一些字段。
根据经验,debug包和release包 的大多数问题都是混淆引起的。通过反射构建对象的时候,类的构造函数也是需要声明keep的
需要小心,Kotlin的 直接接在类后面的够着函数,是没有置灰提示的,很容易漏掉,如果是直接声明的构造函数,
image.png

解决办法

要么对每个类添加@Keep注解,或者添加包的规则。

1
2
#对包下com.test.pkgname包下的类保留构造函数
-keepclassmembers class com.test.pkgname.** { <init>(...)}