可能重复的字符串:
Removing unused strings during ProGuard optimisation使用ProGuard删除记录不会被删除记录
我有几十个记录语句的Android应用程序。我宁愿他们将不会出现在发行版本,所以我用Proguard的像这样的东西在proguard.cfg
文件:
-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的不喜欢,所以我修改了我的记录器类是这样的:
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的某种bug /限制吗?还是只是我不理解它是如何工作的?
你可能想避免proguard黑客,只是使用一个常量:http://stackoverflow.com/questions/4199563/android-util-log-when-publishing-what-can-i-do-not-do如果然后你使用一个常量proguard会在它==假时删除代码行。 – Blundell
的确,这是一个黑客攻击,也是一个丑陋的攻击,但我认为这比将if(DEBUG)放在任何地方都好。生成的代码更清晰,结果在导出的应用程序中是相同的。另外,出于某种原因,如果调试常量是错误的,Eclipse会对死代码抱怨,我不喜欢这样。感谢您的想法,但:) –
请注意,如果您传递基本数据类型,可能仍然有一些死代码。 Proguard不会将基本数据类型移除到相应的“对象”转换。例如。如果你传递一个'int',Proguard将会在'Integer.valueOf(someVar)'行中离开;' – crazymaik