(转)Android中使用BuildConfig.DEBUG必须知道的内幕

一. 坑

在 《Android: 使用BuildConfig.DEBUG优化你的Log输出 & 开启混淆(proguard)的优化配置》 这篇中推荐把DevUtil放到公共库中去, 以方便重用, 但是这里有个巨坑:
主module对library module的依赖都是release依赖
a. 测试环境: AndroidStudio2.2 + Gradle Plugin 2.2.0 + Gradle 2.14.1
b. 在AndroidStudio中创建一个项目, 项目有一个主module和一个library module, 目录结构如下:

1
2
3
.../android-project/             --- 项目目录
.../android-project/app --- 主module
.../android-project/library --- library module

当我们对主module进行构建时, 会先构建library module, 但是library的构建永远是使用release模式构建的. 使用命令打debug包./gradlew :app:assembleDebug, log输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
......
:library:compileReleaseJavaWithJavac UP-TO-DATE
:library:extractReleaseAnnotations UP-TO-DATE
:library:mergeReleaseShaders UP-TO-DATE
:library:compileReleaseShaders UP-TO-DATE
:library:generateReleaseAssets UP-TO-DATE
:library:mergeReleaseAssets UP-TO-DATE
:library:mergeReleaseProguardFiles UP-TO-DATE
:library:packageReleaseRenderscript UP-TO-DATE
:library:packageReleaseResources UP-TO-DATE
:library:processReleaseJavaRes UP-TO-DATE
:library:transformResourcesWithMergeJavaResForRelease UP-TO-DATE
:library:transformClassesAndResourcesWithSyncLibJarsForRelease UP-TO-DATE
:library:mergeReleaseJniLibFolders UP-TO-DATE
:library:transformNative_libsWithMergeJniLibsForRelease UP-TO-DATE
:library:transformNative_libsWithSyncJniLibsForRelease UP-TO-DATE
:library:bundleRelease UP-TO-DATE
......
:app:validateSigningDebug
:app:packageDebug UP-TO-DATE
:app:assembleDebug UP-TO-DATE

BUILD SUCCESSFUL

Total time: 11.475 secs

从log输出可以知道library module打包方式是使用release模式打包的, 因此BuildConfig.DEBUG的值自然是false了. 如果主module的buildType是release, 那么依赖的library module就更不用说了, buildType肯定是release. ./gradlew :app:assembleRelease打release包, log输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
......
:library:packageReleaseRenderscript UP-TO-DATE
:library:packageReleaseResources UP-TO-DATE
:library:processReleaseJavaRes UP-TO-DATE
:library:transformResourcesWithMergeJavaResForRelease UP-TO-DATE
:library:transformClassesAndResourcesWithSyncLibJarsForRelease UP-TO-DATE
:library:mergeReleaseJniLibFolders UP-TO-DATE
:library:transformNative_libsWithMergeJniLibsForRelease UP-TO-DATE
:library:transformNative_libsWithSyncJniLibsForRelease UP-TO-DATE
:library:bundleRelease UP-TO-DATE
......
:app:packageRelease
:app:assembleRelease

BUILD SUCCESSFUL

Total time: 20.195 secs

这么一来, library module中的BuildConfig.DEBUG的值永远都是false. 如《Android: 使用BuildConfig.DEBUG优化你的Log输出 & 开启混淆(proguard)的优化配置》一文中所说 把DevUtil工具类放到公共库中以便代码重用, DevUtil是不能正常工作的, 因为依赖库总是以release模式打包, 导致BuildConfig.DEBUG的值总是false, 进而导致log永远不能输出. 那么解决DevUtil工具类的log输出问题, 就变成了解决依赖库的打包问题.

其实这个打包问题很早就有人提出来了, 大概时2013年5月的时候

关于这个问题的issue地址: https://code.google.com/p/android/issues/detail?id=52962

二. 解决方案
issue上有很多hack, 下面就介绍其中一种比较简洁的hack, 在library的build.gradle文件中添加下面代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
android {
......
......

productFlavors {
create('all') {

}
}
publishNonDefault true
}
configurations {
allDebug
allRelease
}

在主module的build.gradle中用下面的方式对library进行依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//省略其余配置
......
......


dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'com.android.support:appcompat-v7:24.2.1'

//依赖library
debugCompile project(path: ':library', configuration: 'allDebug')
releaseCompile project(path: ':library', configuration: 'allRelease')

//省略其余依赖
.....
.....
}

这样library库中的BuildConfig.DEBUG就会根据buildType生成不同的值.

涉及到DevUtil工具类的地方, 可以结合《Android: 使用BuildConfig.DEBUG优化你的Log输出 & 开启混淆(proguard)的优化配置》阅读

#################################
续:
关于library库, 默认配置是发布release包, 此处有详细说明(其中有关于defaultPublishConfig和publishNonDefault的用法和说明) ==> 我要去看看: “Library Publication
关键部分摘抄如下:

Library Publication

By default a library only publishes its release variant. This variant will be used by all projects referencing the library, no matter which variant they build themselves. This is a temporary limitation due to Gradle limitations that we are working towards removing. You can control which variant gets published:

1
2
3
android {
defaultPublishConfig "debug"
}

Note that this publishing configuration name references the full variant name. Release and debug are only applicable when there are no flavors. If you wanted to change the default published variant while using flavors, you would write:

1
2
3
android {
defaultPublishConfig "flavor1Debug"
}

It is also possible to publish all variants of a library. We are planning to allow this while using a normal project-to-project dependency (like shown above), but this is not possible right now due to limitations in Gradle (we are working toward fixing those as well).

Publishing of all variants are not enabled by default. The snippet below enables this feature:

1
2
3
android {
publishNonDefault true
}

It is important to realize that publishing multiple variants means publishing multiple aar files, instead of a single aar containing multiple variants. Each aar packaging contains a single variant.
Publishing a variant means making this aar available as an output artifact of the Gradle project. This can then be used either when publishing to a maven repository, or when another project creates a dependency on the library project.

Gradle has a concept of default” artifact. This is the one that is used when writing:

1
dependencies {    compile project(':libraries:lib2')}

To create a dependency on another published artifact, you need to specify which one to use:

1
2
3
4
dependencies {
flavor1Compile project(path: ':lib1', configuration: 'flavor1Release')
flavor2Compile project(path: ':lib1', configuration: 'flavor2Release')
}

Important: Note that the published configuration is a full variant, including the build type, and needs to be referenced as such.
Important: When enabling publishing of non default, the Maven publishing plugin will publish these additional variants as extra packages (with classifier). This means that this is not really compatible with publishing to a maven repository. You should either publish a single variant to a repository OR enable all config publishing for inter-project dependencies.
References:

https://code.google.com/p/android/issues/detail?id=52962
http://tools.android.com/tech-docs/new-build-system/user-guide

文章目录
,