Proguard 删除抽象 class 中未使用的重写方法

Proguard removes overridden methods in abstract class as unused

Proguard 正在删除抽象 class 中未使用的覆盖方法,即使它们在父 class 中使用。 这是显示行为的参考实现

public abstract class Animal {
    Animal() {
        born();
    }

    abstract void born();
}

public abstract class Human extends Animal {
    @Override
    void born() {
        System.out.println("Human is born.");
    }
}

保留属性定义为:

-keep public class test.Human {
    public *;
}

Proguard 将 Human class 中重写的 born() 方法删除为未使用,即使它是从 Animal class 的构造函数中使用的。生成的映射文件是

test.Animal -> test.a:
    void born() -> a
test.Human -> test.Human:

如果class Human不是抽象的就不存在这个问题。如果 class Human 是非抽象的,则生成的映射文件是

test.Animal -> test.a:
    void born() -> a
test.Human -> test.Human:
    void born() -> a

可以看到,本例中保留了方法born()

这是混淆器中的错误吗?或者是否有任何优化设置可以提供所需的行为?

我在 android studio 中使用混淆器。

您将 ProGuard 配置为保留 public 方法,而 born() 是包私有的。你的配置应该是这样的。

-keep public class test.Human {
    <methods>;
}

它将保留 Human class 的所有包私有(默认)方法。

如果你想保留方法但仍然允许对它们进行混淆,你可以使用这样的东西:

-keep, allowobfuscation public class test.Human {
    <methods>;
}

由于问题仅在这些 class 是库的一部分(并且库中没有任何具体实现)时才会出现,因此我采取了简单的方法并添加了 -dontshrink 以保留(混淆)所有 classes 和方法。

在大多数情况下; class 发布库时不需要进行方法缩减。

我仍然认为忽略重写的方法实现是使用图中的错误。我已经在 proguard bug tracker 中提交了一个 bug。 https://sourceforge.net/p/proguard/bugs/574/