android R8 如何保留类名而不是成员

android R8 how to keep class name but not members

提问人:Jade 提问时间:10/8/2023 更新时间:10/9/2023 访问量:53

问:

现在我有一个名为“ABC”的注释,我想保留具有由“ABC”注释的成员的类,例如

class Test {
  @ABC
  var testField: Int = 0
  
  var testField2: Int = 0
 }

我想保留类名“Test”,但混淆成员名“testField”、“testField2”。有没有办法做到这一点? 每一条有见地的评论都受到高度赞赏......

安卓 ProGuard Android-R8

评论


答:

0赞 plplmax 10/9/2023 #1

请尝试以下操作:

-if class com.example.* {
    @com.example.ABC <fields>;
}

-keepnames class com.example.*
0赞 sgjesse 10/9/2023 #2

如果要将其应用于程序中实际使用的类,则可以使用以下规则:

# For all classes used in the program keep and obfuscate fields annotated with @ABC.
-if class *
-keepclasseswithmembers,allowobfuscation class <1> {
  @ABC <fields>;
}
# Keep the class name for classes which has at least one used field annotated with @ABC.
-if class * {
  @ABC <fields>;
}
-keep class <1>

如果您希望它适用于所有类(而不仅仅是程序中使用的类),请删除第二行 。-if class *

在问题中,只有一个字段被注释,上面的规则将只保留注释的字段。如果要将所有字段保留在至少一个字段注释的类上,则还必须添加以下规则:

# Keep all fields for classes which has at least one used field annotated with @ABC.
-if class * {
  @ABC <fields>;
}
-keep,allowobfuscation class <1> {
  <fields>;
}

如果注释具有运行时保留,并且您希望该注释保留以进行运行时反射,则还必须添加以下规则:ABC

-keepattributes RuntimeVisibleAnnotations,AnnotationDefault
-keep @interface ABC

最后请注意,由于该类是 Kotlin 类,因此这些字段还生成了 getter 和 setter,它们不受上述任何规则的约束。不幸的是,没有通用的方法可以精确地保留所保留的字段的 getter 和 setter。以下规则将保留所有公共 getter 和 setter 在至少有一个字段注释为 :@ABC

-if class * {
  @ABC <fields>;
}
-keep class <1> {
  public *** get*();
  public void set*(...);
}

但是,此规则有一个不幸的副作用,即保留这些 getter 和 setter 的所有字段,因此,如果您只想保留带有此注释的字段,则行不通。@ABC

可以在不提供任何代码的情况下对 getter 和 setter 进行注释:

public class Test {
  @ABC var testField: Int = 0
  @ABC get
  @ABC set

  var testField2: Int = 0
 }

有了它,您可以将初始规则更新为

-keepclasseswithmembers,allowobfuscation class <1> {
  @ABC <fields>;
  @ABC *** get*();
  @ABC void set*(***);
}

仅保留带注释的字段和带注释的 getter 和 setter。