【问题标题】:How to keep class' members untouched if it contains a field with an annotation in proguard如果在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 应用时,这个包被排除在混淆之外。

标签: android google-cloud-firestore proguard obfuscation android-r8


【解决方案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
猜你喜欢
  • 2012-07-22
  • 1970-01-01
  • 2021-09-10
  • 2010-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-16
相关资源
最近更新 更多