使用Proguard时如何保留/排除特定的包装路径?


110

我想从ProGuard中排除一些文件路径。例com.myapp.customcomponents

我怎样才能做到这一点?我讨厌为该目录中的每个自定义组件文件放置-keep标志。

我尝试了以下方法,但不起作用:

-keep public class com.myapp.customcomponents.*

Answers:


241

您没有指定以什么方式不起作用。您的配置将所有公共类的名称保留在指定的包中:

-keep public class com.myapp.customcomponents.*

以下配置将所有公共类的名称保留在指定的包及其子包中:

-keep public class com.myapp.customcomponents.**

以下配置将指定包及其子包中所有公共/受保护的类/字段/方法的名称保留:

-keep public class com.myapp.customcomponents.** {
  public protected *;
}

6
双星号(**)不再编译(Android Studio 4.0)
Daniel

Android Studio 4.x对于双星号(**)将显示诸如“未解析的类名”之类的错误,但它将按预期工作。
Mahmudul Hasan Shohag

55

在ProGuard配置的底部添加以下行:

-keep class com.facebook.** { *; }

相应地替换软件包名称,此处软件包com.facebook将从ProGuard中排除。


13
为什么要一起使用和不要使用
Jongz Puangput 2015年

@Jongz Puangput,如果我正确-如果应用程序不使用com.facebook软件包,则在构建时将显示注释“配置引用未知类...”。-dontwarn禁用此注释。
Yura Shinkarev '16

14
什么{ *; }意思
穆罕默德·巴巴尔

15
@MuhammadBabar我的意思是每个范围中的每个成员,方法,类,总之!
Omar El Don

1

许多人似乎建议-keep class com.myapp.customcomponents.** { *; }将路径排除在处理之外。看这里:

  1. 从proguard中排除软件包
  2. 使Proguard完全忽略软件包
  3. 防止目录混淆

该解决方案的问题在于,仍然存在某种程度的混淆,这可能会破坏您的代码。您可以在打印输出中看到该映射:

java.lang.String toString() -> toString
int getMemoizedSerializedSize() -> getMemoizedSerializedSize
void setMemoizedSerializedSize(int) -> setMemoizedSerializedSize
int getSerializedSize() -> getSerializedSize
boolean equals(java.lang.Object) -> equals
int hashCode() -> hashCode

我选择的解决方案是一个两步过程。首先,使用injars过滤器选择我要处理的程序包路径。可以将其他程序包路径添加为库。

-injars       artifacts/in.jar(org/toprocess/**.class)
-outjars      out/processed.jar
-libraryjars  artifacts/in.jar(org/skipped/**.class)
-libraryjars  artifacts/in.jar(org/moreskipped/**.class)

其次,将已处理的jar与原始jar合并,但仅合并那些被跳过的路径。

-injars  out/processed.jar
-injars  artifacts/in.jar(org/skipped/**.class)
-injars  artifacts/in.jar(org/moreskipped/**.class)
-outjars out/merged.jar

-dontshrink
-dontoptimize
-dontobfuscate

结果是合并的jar,它是已处理的程序包路径和跳过的路径的组合。如果有人可以提供一种方法来完全跳过对某些路径的处理(我没有找到),则此练习无效。


1

使用Android Studio 4.0对我有用的是:

-keepclassmembers class com.myapp.customcomponents.* {
    <fields>;
    <init>();
    <methods>;
}

其他答案中的双星号(**)对我不起作用。我还尝试了R8的上述配置,效果很好。


这个答案是我认为最新的答案。谢谢。
Gogo-the-Cat
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.