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, 目录结构如下:

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

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

......
: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输出如下:

......
: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项目中BuildConfig.DEBUG值总为false的解决方案.png
  1. 在library的build.gradle文件中添加下面代码:
android {
    ......
    ......

    productFlavors {
        create('all') {

        }
    }
    publishNonDefault true
}
configurations {
    allDebug
    allRelease
}
  1. 在主module的build.gradle中用下面的方式对library进行依赖
//省略其余配置
......
......


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:

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:

>```
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:

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:

>`dependencies {    compile project(':libraries:lib2')}`

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

>```
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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容