ProGuard可以从ALWAYS返回常量的方法中删除条件代码吗?

Ric*_*ral 5 optimization android proguard

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

if(BuildConfig.DEBUG) {
    // do something...
}
Run Code Online (Sandbox Code Playgroud)

如果ProGurad评估BuildConfig.DEBUG为false,if则会从最终字节码中删除其中的代码块.这是按预期工作的.

然而,随着Android新构建系统的推出,我们现在拥有许多我们以前没有的能力.我正在利用它创造一个新的buildType,我称之为QA.有了这个我添加一个BuildConfig.QA常量,相应的构建类型将是真或假.

现在我有一些代码片段,我需要测试它是a DEBUG还是QA构建,如下所示:

if(BuildConfig.DEBUG || BuildConfig.QA) {
    // do something...
}
Run Code Online (Sandbox Code Playgroud)

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

public static boolean isDevelopmentBuild() {
    return BuildConfig.DEBUG || BuildConfig.QA;
}
Run Code Online (Sandbox Code Playgroud)

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

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

Ern*_*ill 6

为什么不在BuildConfig界面中添加常量DEV,比如

boolean DEBUG = ...
boolean QA = ...
boolean DEV = DEBUG | QA;
Run Code Online (Sandbox Code Playgroud)

它将是一个编译时常量(鉴于DEBUG和QA是在编译时定义的),因此ProGuard将能够基于just进行代码消除

if (BuildConfig.DEV) { ...
Run Code Online (Sandbox Code Playgroud)

  • IIRC,IntelliJ有一个"@noinspect"注释,您可以将其应用于代码以关闭特定点的检查.不,我的意思是"|",对于`boolean`s来说,它是一个等同于`||`的非短路.没有真正的理由使用它而不是|| 这里 - 只是美学! (2认同)