如何阻止R8/ProGuard移除Kotlin合成默认构造方法?
为什么R8会移除Kotlin数据类的合成构造方法(即使添加了keep规则)?
你的keep规则之所以没生效,核心原因是**<init>(...)不会匹配带有synthetic修饰符的构造方法**,而R8默认会把未被显式保留的合成方法视为内部实现细节进行移除。
具体原因分析
你定义的Kotlin数据类因为带默认参数,编译器生成了带DefaultConstructorMarker参数的合成构造方法,但你的规则-keep @com.squareup.moshi.JsonClass class * { <init>(...); }只匹配普通的非合成构造方法。R8在代码优化时,会认为这个合成构造没有被外部直接引用(即使Moshi通过反射访问),所以依然会将其移除。
解决办法
需要在keep规则中明确指定要保留合成构造方法,可以用两种方式实现:
- 精确匹配目标合成构造的参数签名
-keep @com.squareup.moshi.JsonClass class * { // 匹配带DefaultConstructorMarker的合成构造 <init>(Ljava/lang/String;Ljava/lang/String;ILkotlin/jvm/internal/DefaultConstructorMarker;); // 保留普通构造方法(按需添加) <init>(Ljava/lang/String;); }
- 通用匹配所有合成构造方法(适合多个类的场景)
-keep @com.squareup.moshi.JsonClass class * { // 保留所有合成构造 * synthetic <init>(...); // 保留普通构造方法 <init>(...); }
额外说明
另外,你给类添加了@JsonClass(generateAdapter = true),Moshi会自动生成类型安全的适配器类,通常不需要直接反射构造方法。如果你的场景确实依赖反射这个合成构造,上面的规则就能解决R8移除的问题。
内容的提问来源于stack exchange,提问作者der_Fidelis
相关产品推荐
相关产品推荐

