使用proguard删除日志调用会留下StringBuilders

时间:2014-03-28 12:40:43

标签: java proguard

我有一个用于记录的静态方法的类,例如:

我试图使用ProGuard删除所有这些内容。我不想禁用它们(无论如何都使用逻辑),我希望它们在反编译时消失。

它成功删除了对我的日志记录方法的调用,但留下了连接的字符串。它完全删除了已修复的字符串。

这是我的ProGuard设置:

-assumenosideeffects class com.mypackage.Log { *; }

这是我的来源:

void doSomething(String name) {
    Log.verbose("Hello!");
    Log.verbose("My name is " + name);
    ...
}

这是它反编译的内容:

void a(String a) {
    new StringBuilder("My name is ").append(a);
    ...
}

这就是我希望它反编译为:

void a(String a) {
    ...
}

对于此示例,假设稍后在方法中使用name参数(即,它不应该完全优化)。

我是否还应该将assumenosideeffects用于StringBuilder?我确实在其他地方使用StringBuilders,我确实想保留它。那会将它们移除吗?

1 个答案:

答案 0 :(得分:2)

检查结果是否符合预期是件好事。在这种情况下,ProGuard不知道StringBuilder操作没有任何净效应,因此它会让它们进入。您可以在问题Removing unused strings during ProGuard optimisation中找到相当完整的讨论。

ProGuard的最新版本有一些启发式技术可以解决像这样的简单案例。 ProGuard的商业扩展DexGuard实现了一种称为逃逸分析的更先进的技术;它可以删除调用结果。

(我是ProGuard和DexGuard的开发者)