【问题标题】:How to keep/exclude a particular package path when using proguard?使用 proguard 时如何保留/排除特定的包路径?
【发布时间】:2011-06-17 08:37:05
【问题描述】:

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

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

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

-keep public class com.myapp.customcomponents.*

【问题讨论】:

    标签: android proguard


    【解决方案1】:

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

    -keep public class com.myapp.customcomponents.*
    

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

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

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

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

    【讨论】:

    • 双星号 (**) 不再编译 (Android Studio 4.0)
    • Android Studio 4.x 会针对双星号 (**) 显示“未解析的类名”等错误,但它会按预期工作。
    • 已修复,不会在upcoming releases, check details here中报错
    【解决方案2】:

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

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

    相应地替换包名称,这里包com.facebook将被排除在ProGuard之外。

    【讨论】:

    • 为什么要保持和不要一起使用
    • @Jongz Puangput,如果我是对的 - 如果应用程序不使用 com.facebook 包,那么在构建时将显示注释“配置引用未知类......”。 -dontwarn 禁用此注释。
    • { *; } 是什么意思?
    • @MuhammadBabar i 表示每个范围内的每个成员、方法、类,总之一切!
    【解决方案3】:

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

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

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

    【讨论】:

    • 这个答案是我认为的最新答案。谢谢。
    【解决方案4】:

    很多人似乎都推荐-keep class com.myapp.customcomponents.** { *; } 作为排除处理路径的一种方式。见这里:

    1. exclude packages from proguard
    2. Make Proguard completely ignore package
    3. Prevent a directory from proguard obfuscation

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

    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,它是已处理的包路径和跳过的路径的组合。如果有人可以提供一种方法来完全跳过某些路径的处理(我还没有找到),那么这个练习是无效的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-01
      • 2018-05-10
      • 2017-04-24
      • 1970-01-01
      • 2021-12-29
      • 2011-10-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多