Possible Duplicate:
Removing unused strings during ProGuard optimisation
我有一个包含数十条日志记录语句的 Android 应用程序。我希望它们不会出现在发布版本中,所以我在 proguard.cfg
文件中使用了 Proguard 和类似的东西:
-assumenosideeffects class android.util.Log {
public static *** d(...);
}
但问题是有很多Log.d("something is "+ something)
,虽然Log.d()
语句是从字节码中删除,字符串仍然存在。
所以,关注 this回答,我创建了一个简单的包装类,类似于:
public class MyLogger {
public static void d(Object... msgs) {
StringBuilder log = new StringBuilder();
for(Object msg : msgs) {
log.append(msg.toString());
}
Log.d(TAG, log.toString());
}
}
然后我编辑了我的 proguard.cfg
:
-assumenosideeffects class my.package.MyLogger {
public static *** d(...);
}
但是在生成的字节码中仍然可以找到字符串!
除此之外,我使用的是 Android SDK 提供的标准 proguard.cfg
。我做错了吗?
编辑:检查生成的字节码后,我看到字符串在那里,但并没有像我想的那样一个接一个地附加。它们被存储在数组中。为什么?将它们作为可变参数传递给我的方法。看起来 ProGuard 不喜欢这样,所以我修改了我的 logger 类:
public static void d(Object a) {
log(a);
}
public static void d(Object a, Object b) {
log(a, b);
}
(... I had to put like seven d() methods ...)
private static void log(Object... msgs) {
(same as before)
}
这很难看,但现在字符串在字节码中无处。
这是 ProGuard 的某种错误/限制吗?还是只是我不明白它是如何工作的?
最佳答案
针对不同数量的参数使用不同方法的解决方案可能是最方便的解决方案。具有可变数量参数的单个方法会更好,但当前版本的 ProGuard 不够智能,无法删除所有未使用的代码。
java 编译器将可变数量的参数编译为单个数组参数。在调用方面,这意味着创建一个大小合适的数组,填充元素并将其传递给方法。 ProGuard 看到正在创建数组,然后用于在其中存储元素。它没有意识到(还)它没有用于实际有用的操作,方法调用消失了。结果,数组的创建和初始化被保留了。
如果您期望某些特定的优化,最好检查已处理的代码。
关于android - 使用 ProGuard 删除日志不会删除正在记录的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7086920/