Android 开发中一般会通过 BuildConfig.DEBUG 判断是否是 Debug 模式,从而做一些在 Debug 模式才开启的特殊操作,比如打印日志。这样好处是不用在发布前去主动修改,因为这个值在 Debug 模式下为 true,Release 模式下为 false。

1. 问题

如果应用只有一个 Module 没有问题,Debug 模式下 BuildConfig.DEBUG 会始终为 false。如果现在有两个 Module,分别为 App 和 Lib,且 App 依赖 Lib,在 Lib 内有工具类 LogUtils,代码如下:

当我们在 App Module 内调用 LogUtils 时我们会发现始终无法打印日志,因为上面的 BuildConfig.DEBUG 会始终为 false。为什么呢?

2. 原因

BuildConfig.java 是编译时自动生成的,并且每个 Module 都会生成一份,以该 Module 的 packageName 为 BuildConfig.java 的 packageName。所以如果你的应用有多个 Module 就会有多个 BuildConfig.java 生成,而上面的 Lib Module import 的是自己的 BuildConfig.java,编译时被依赖的 Module 默认会提供 Release 版给其他 Module 或工程使用,这就导致该 BuildConfig.DEBUG 会始终为 true。

3. 解决方案

根据上面分析的原因,目前我们有两个思路:

(1) 始终调用最终运行的 Module 的 BuildConfig,因为它没有被任何其他 Module 依赖,所以 BuildConfig.DEBUG 值会准确。

(2) 让被依赖的 Module 提供除 Release 版以外的其他版本。

3.1 解决方案一:使用其他的 BuildConfig.java

如果 Lib Module 中能够 import 到外层真正运行 App 的 BuildConfig 就 ok 了,如下:

通过反射得到真正执行的 Module 的 BuildConfig,在自己的 Application 内调用:

AppUtils.syncIsDebug(getApplicationContext());

这样看起来达到目的了。

但仔细看看会发现这种解决方案还是有问题,因为 BuildConfig.java 的 packageName 是 Module 的 Package Name,即 AndroidManifest.xml 中的 package 属性,而 context.getPackageName() 得到的是应用的 applicationId,这个 applicationId 通过 build.gradle 是可以修改的。所以当 build.gradle 中的 applicationId 与 AndroidManifest.xml 中的 package 属性不一致时,上面的反射查找类路径便会出错。

PS:这种方案还有个变种就是通过 android.app.ActivityThread.currentPackageName 得到包名,从而省去传递 Context 初始化的步骤,但依然有 applicationId 被修改后类查找不到类似的问题。

3.2 解决方案二:Lib publishNonDefault

让被依赖的 Module 提供除 Release 版以外的其他版本,这种方案需要将所有被依赖 library 中添加:

android {

publishNonDefault true

}

表示该 Module 不使用默认配置,这样会同时打包其他版本,包括 Debug 版。另外需要在 App Module 中将其依赖的 library 如下逐个添加:

dependencies {

releaseCompile project(path: ':library', configuration: 'release')

debugCompile project(path: ':library', configuration: 'debug')

}

表示依赖不同版本的依赖 Module。

然而这种方式所有 Module 配置都需要修改,侵入性太强。

3.3 最终解决方案:使用 ApplicationInfo.FLAG_DEBUGGABLE

既然 BuildConfig 的方式行不通,我们反编译 Debug 包和 Release 包对比看看有没有其他的区别,会发现他们 AndroidManifest.xml 中 application 节点的 android:debuggable 值是不同的。Debug 包值为 false,Release 包值为 true,这是编译自动修改的。所以我们考虑通过 ApplicationInfo 的这个属性去判断是否是 Debug 版本,如下:

在自己的 Application 内调用进行初始化,

AppUtils.syncIsDebug(getApplicationContext());

这样以后调用 AppUtils.isDebug() 即可判断是否是 Debug 版本,比如在上面的 LogUtils 中。同时适用于 Module 是 Lib 和 applicationId 被修改的情况,比 BuildConfig.DEBUG 靠谱的多。

这个方案有个注意事项就是自己 App Module 中不能主动设置 android:debuggable,否则无论 Debug 还是 Release 版会始终是设置的值。当然本身就没有自动设置的必要。

转载于:https://www.cnblogs.com/dongweiq/p/9075531.html

解决依赖的moduleBuildConfig.DEBUG总是未false的问题相关推荐

  1. 解决ThinkPHP3.2 将Debug 关闭 设置为False 报页面错误 请稍后再试

    1.最近系统要上线,就把Index.php中的debug 关闭 设置成false,结果出现如下的错误 2.修改config.php文件,加入   'SHOW_ERROR_MSG' => TRUE ...

  2. Gradle 使用技巧(四) - 如何定位和解决依赖冲突

    1. 前言 随着业务的复杂度加深,我们免不了要引入许多的第三方开源库,也不可避免的会出现依赖冲突的错误.最常见的是V7.V4包之间的冲突. 2. 如何定位依赖冲突 解决依赖冲突很简单,难得是如何去定位 ...

  3. 升级python2至python3解决依赖关系

    1.最小化安装centos7,在升级python3的时候会出现很多包未安装,为解决依赖关系: yum -y install gcc gcc-c++ zlib zlib-devel libffi-dev ...

  4. python2和python3关系_升级python2至python3解决依赖关系

    1.最小化安装centos7,在升级python3的时候会出现很多包未安装,为解决依赖关系: yum -y install gcc gcc-c++ zlib zlib-devel libffi-dev ...

  5. Windows下解决依赖动态库问题:bat脚本实现自动复制dll文件

    1. 问题 Windows下,exe文件在设计实现时可能依赖某些动态库(*.dll文件),这些在调试台调试或在本机运行因为指定了包含库文件或者指定了环境变量,使得运行时可以找到并调用这些文件.但是环境 ...

  6. Deb包安装如何解决依赖问题

    在 Unbuntu 系统上安装各种软件时,经常会遇到各种各样的依赖问题而导致安装无法进行.我作为一枚 Linux 小白正深受其苦,经常越弄越乱导致不得不重装系统(哭).通常来说,这类问题可以通过 更换 ...

  7. gradle项目 避免每次下载gradle文件/解决依赖下载慢的问题

    参考:https://www.jb51.net/article/114276.htm 避免每次下载gradle文件 一.使用已存在的 gradle 版本 打开目录 ~/.gradle/wrapper/ ...

  8. 最新版OpenWrt编译教程,解决依赖问题

    最新版OpenWrt编译教程,解决依赖问题 参考文章: (1)最新版OpenWrt编译教程,解决依赖问题 (2)https://www.cnblogs.com/jzssuanfa/p/7400840. ...

  9. 解决Vue刷新一瞬间出现样式未加载完或者出现Vue代码问题

    解决Vue刷新一瞬间出现样式未加载完或者出现Vue代码问题 参考文章: (1)解决Vue刷新一瞬间出现样式未加载完或者出现Vue代码问题 (2)https://www.cnblogs.com/jiah ...

最新文章

  1. 【JavaScript总结】JavaScript语法基础:JS编码
  2. substr()函数——mysql:截取字符串子串
  3. Docker现已加入苹果M1“豪华午餐”,程序员换新Mac的理由又多了一条
  4. Android自定义View详解,知乎上转疯了!
  5. MVCC在MySQL的InnoDB中的实现
  6. iOS之深入解析KVC的底层原理和自定义KVC的实现
  7. 迭代器自定义遍历对象
  8. python功能选择模块_python – 组合功能和功能模块
  9. 前端学习(606):计算机基础
  10. mybatis学习(54):鉴定器
  11. 2020年互联网大厂中秋礼盒PK!看看你的礼盒怎么样
  12. 删除本地.svn文件
  13. ubuntu进入桌面自动启动脚本_Ubuntu程序开机自动启动设置(服务和自动运行配置文件)的几种方法...
  14. Artstudio Pro for mac(绘图和编辑工具)
  15. 操作系统之三种进程通信方式
  16. 360天擎卸载带密码_如何卸载360企业版
  17. excel数字点一下才变为数值的批量快捷操作
  18. 历年四级作文真题范文
  19. 电脑修改默认远程端口3389的方法(☆亲测)
  20. php读取xml文件,并存入数据库

热门文章

  1. 洛谷 [P1314] 聪明的质检员(NOIP2011 D2T2)
  2. 最小生成树之Kruskal算法
  3. android开发之-软件设置保存-快速学会使用SharedPreferences篇-实测
  4. 计算机科学与技术导论
  5. 用ul和li实现表格table效果 (转)
  6. ArcGIS.Server.9.3和ArcGIS API for Flex的GeometryService和buffer分析(十)
  7. C# ToString()方法
  8. 初始html(常用标签)
  9. 函数中{}输出格式详解(C#)
  10. Java并发编程 LockSupport源码分析