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

hc8w905p  于 2023-10-14  发布在  Android
关注(0)|答案(2)|浏览(108)

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

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

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

ioekq8ef

ioekq8ef1#

请尝试以下操作:

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

-keepnames class com.example.*
ix0qys7i

ix0qys7i2#

如果你想把这个应用到你的程序中实际 * 使用 * 的类,你可以使用这个规则:

# 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注解的类上保留 all 公共getter和setter:

-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。

相关问题