如果在proguard中包含带有注释的字段,如何保持类的成员不受影响

Posted

技术标签:

【中文标题】如果在proguard中包含带有注释的字段,如何保持类的成员不受影响【英文标题】:How to keep class' members untouched if it contains a field with an annotation in proguard 【发布时间】:2020-11-19 14:06:20 【问题描述】:

如果类包含带注释的字段,如何配置 proguard/R8 以保留类的所有字段和方法?

我有课

public class MyDocument 
  @DocumentId
  private String foo;

  private String bar;

  public getFoo()  .. 
  public getBar()  .. 

我能够让它不删除 foo

-keepclassmembers class * 
  @a.b.c.DocumentId <fields>;
  @a.b.c.DocumentId <methods>;

但它仍然删除 getBar()

有没有办法说“如果同一类中的某个字段包含注释,则不要删除类中的任何方法或字段?

这里的用例是它们是firestore's toObject使用的DTO类 我不想根据类名进行匹配,因为这条规则将适用于许多类。

【问题讨论】:

如果我是正确的,你不希望你的模型类被 R8 规则混淆,那么你可以使用一行 -keep class com.example.example.models.** *; 你可以将所有模型类放入一个包中当 proguard 应用时,这个包被排除在混淆之外。 【参考方案1】:

I just read about -keepclasseswithmembers,相当于根据类的内容推断出的@Keep

-keepclasseswithmembers class *  
  @a.b.c.DocumentId <fields>;

真正归结为-keepclassmembers 的更严格的替代方法是使用 r8 可以检测到的东西(例如,保留=运行时的注释)注释 DTO,然后在规则中定位该注释:

-keepclassmembers @a.b.c.Dto class *

【讨论】:

您的第一个解决方案不起作用。我试过了。该解决方案正是我在我的问题中提到的,它仅用于保留带注释的字段,而不是其“兄弟”字段。第二种解决方案可能会起作用,但我的目标是不要用仅用于 proguard 的东西污染代码 等等,你已经尝试过keepclasseswithmembers?请注意withmembers 部分-我没有在您的帖子中看到它。 ? 抱歉。我的错。我提到的不是 with 成员,但我已经尝试过,但它也不起作用:getBar 仍然被删除。我的理解是,该指令是为了保护一个类不被删除,而不是它的内容【参考方案2】:

您应该能够使用这样的条件规则:

-if class * 
  @a.b.c.DocumentId *** *;

-keep class <1> 
  *;

确切地说,一个类有一个带有注释的字段,保留该类的所有成员。

【讨论】:

取决于您如何确保带有a.b.x.DocumentId 注释的字段在程序中,这可能无法按预期工作,请参阅issue 162921738。

以上是关于如果在proguard中包含带有注释的字段,如何保持类的成员不受影响的主要内容,如果未能解决你的问题,请参考以下文章

如何在我的 Android 库 (AAR) 中包含 proguard 配置

如何防止 ProGuard 在输出 jar 中包含引用的库

Proguard 删除 Android 应用程序中的注释

导出为 PDF 时如何在文本字段中包含图像和表格?

使用带有 proguard 关闭力的 jsoup 关闭

如何使 ProGuard 保留整个(整个)类(带有字段和方法)而不使用“-keep”