You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让@Keep注解实现与ProGuard -keep规则等效的类及成员保留效果

核心原因

R8/ProGuard 对官方@Keep注解的默认处理逻辑和预期的全量保留效果并不一致:

  • 默认规则只会把被@Keep标记的类本身保留下来,不做裁剪、不混淆类名
  • 类内部的字段、方法、构造器这些成员,只有自己被单独打上@Keep才会被保留,类级别的@Keep标记不会自动覆盖所有内部成员

单独打aar的时候看起来生效,是因为库模块构建时默认不会激进裁剪自身对外暴露的公共API成员;但App层级构建时,R8会做全项目的跨模块优化,把没有被App代码实际调用的类成员判定为可混淆对象,就出现了“类留着、成员被混淆”的问题。

原有的-keep,includedescriptorclasses public class com.demo.api.** { *; }规则,是会把匹配到的类的所有内容——包括类本身、所有成员、甚至方法/字段描述符里引用到的关联类——全部保留不混淆,这和默认@Keep的语义有本质区别。


对齐效果的配置方法

  1. 配置库的Consumer ProGuard传递规则
    这类规则会被自动打包进aar,App集成时会自动加载,不需要App端手动改任何配置。
    • 在库模块的build.gradle中声明consumer规则文件:
      android {
          // 其他原有配置
          consumerProguardFiles "consumer-rules.pro"
      }
      
    • 在库模块根目录新建consumer-rules.pro文件,添加和原keep规则等价的注解匹配规则:
      # 全量保留所有被@Keep标记的类:保留类本身、所有内部成员,同时连带保留类描述符引用的关联类
      -keep,includedescriptorclasses @androidx.annotation.Keep class * { *; }
      
  2. 清理旧的硬编码保留规则
    删掉之前库模块里写死包路径的通配keep规则,后续只需要在需要全量保留的类上打@Keep注解,不需要再单独给每个成员、每个类重复标注。
  3. 校验规则是否正确打包
    打出release版aar后,解压包文件查看META-INF/proguard/目录下的内容,确认上面的keep规则已经被打进aar,避免规则只在库本地构建生效、没有传递到App端。

避坑提醒

  • 别把上面的keep规则写到库模块默认的proguard-rules.pro里:这个文件的规则只在库自身混淆构建时生效,不会被打包进aar传给App,必然会导致集成时规则失效。
  • 一定要用官方提供的androidx.annotation.Keep注解:自己自定义的同名注解R8不认识,不会触发保留逻辑。
  • 原规则里的includedescriptorclasses参数不能省:缺了这个参数,类的方法、字段引用到的其他自定义类还是会被混淆,后续很容易出现反射调用失败、类型转换报错的问题。

内容的提问来源于stack exchange,提问作者tvanlaerhoven

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.28 06:27:04