在我的Android应用程序上,我一直在使用这样的条件代码:
if(BuildConfig.DEBUG) {
// do something...
}
如果ProGurad将BuildConfig.DEBUG
评估为false,则if
内的代码块将从最终字节码中删除。这是按预期工作的。
然而,随着Android新构建系统的推出,我们现在拥有许多我们以前没有的能力。我正在通过创建一个新的buildType
来利用它,我称之为 QA 。有了这个,我添加了一个BuildConfig.QA
常量,它对应于构建类型将是真或假。
现在我有一些代码片段,我需要测试它是DEBUG
还是QA
版本,如下所示:
if(BuildConfig.DEBUG || BuildConfig.QA) {
// do something...
}
但是在整个地方写这个很麻烦。相反,我决定在我的utils类上创建一个静态方法,如下所示:
public static boolean isDevelopmentBuild() {
return BuildConfig.DEBUG || BuildConfig.QA;
}
问题是,使用这种方法,任何条件代码都不会像过去那样被删除。之前,ProGuard可以将这些常量评估为false并删除代码。现在,它必须调用一个方法并检查返回值。
但是由于该方法的返回值是常量,ProGuard是否有可能以一种知道返回值始终为常量值(在运行时)的方式评估方法调用并从最终中删除代码字节码?
答案 0 :(得分:6)
为什么不在BuildConfig界面中添加常量DEV,比如
boolean DEBUG = ...
boolean QA = ...
boolean DEV = DEBUG | QA;
它将是一个编译时常量(假设在编译时定义了DEBUG和QA),因此ProGuard将能够基于
进行代码消除if (BuildConfig.DEV) { ...
答案 1 :(得分:3)
ProGuard应该能够内联方法并删除调试代码。您可以使用像dexdump
这样的Dalvik字节码反汇编器或反编译器轻松检查它。
欧内斯特弗里德曼 - 希尔的解决方案可能更可取。实际上,javac编译器已经删除了由设置为false
的常量布尔标志保护的代码。它节省了一些处理,您不需要依赖ProGuard。同样,您可以使用反汇编程序或反编译器检查结果。