5

在我的 Android 应用程序中,我一直在使用这样的条件代码:

if(BuildConfig.DEBUG) {
    // do something...
}

如果 ProGurad 评估BuildConfig.DEBUG为假,则内部的代码块if将从最终字节码中剥离。哪个按预期工作。

然而,随着 Android 新构建系统的引入,我们现在拥有了许多以前没有的能力。我通过创建一个buildType我称之为QA的新项目来利用这一点。有了这个,我添加了一个BuildConfig.QA常量,该常量将根据构建类型为真或假。

现在我有一些代码需要测试它是 aDEBUG还是QAbuild,如下所示:

if(BuildConfig.DEBUG || BuildConfig.QA) {
    // do something...
}

但是这样写很麻烦。相反,我决定在我的 utils 类上创建一个静态方法,如下所示:

public static boolean isDevelopmentBuild() {
    return BuildConfig.DEBUG || BuildConfig.QA;
}

问题在于,使用这种方法,任何条件代码都不会像以前那样被删除。以前,ProGuard 可以将这些常量评估为 false 并剥离代码。现在,它必须调用一个方法并检查返回值。

但是由于该方法的返回值是常量,ProGuard 是否有可能以一种知道返回值始终是常量值(在运行时)并从最终字节码中删除代码的方式评估方法调用?

4

2 回答 2

6

为什么不向您的 BuildConfig 界面添加一个常量 DEV,例如

boolean DEBUG = ...
boolean QA = ...
boolean DEV = DEBUG | QA;

这将是一个编译时常量(假设 DEBUG 和 QA 是在编译时定义的),因此 ProGuard 将能够仅基于

if (BuildConfig.DEV) { ...
于 2013-08-04T12:24:48.663 回答
3

ProGuard 应该能够内联该方法并删除您的调试代码。您可以使用 Dalvik 字节码反汇编器dexdump或反编译器轻松检查。

Ernest Friedman-Hill 的解决方案可能更可取。实际上是 javac 编译器已经删除了由设置为false. 它节省了一些处理,您不需要依赖 ProGuard。同样,您可以使用反汇编器或反编译器检查结果。

于 2013-08-06T16:32:19.907 回答