buildconfig.java debug_Android 技巧 - Debug 判断不再用 BuildConfig

本文探讨了Android多模块项目中BuildConfig.DEBUG始终为false的问题,分析其原因并提出三种解决方案,包括调用正确模块的BuildConfig、让依赖模块提供非默认版本及使用ApplicationInfo.FLAG_DEBUGGABLE。
部署运行你感兴趣的模型镜像

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

1. 问题

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

65c5e5adf5e8d2c39f67e225340bc41a.png

当我们在 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 了,如下:

8474c183a8829c9b8578af109298e64e.png

通过反射得到真正执行的 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 版本,如下:

e82adc5dda60b805edf9a6dd278722be.png

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

AppUtils.syncIsDebug(getApplicationContext());

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

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

您可能感兴趣的与本文相关的镜像

AutoGPT

AutoGPT

AI应用

AutoGPT于2023年3月30日由游戏公司Significant Gravitas Ltd.的创始人Toran Bruce Richards发布,AutoGPT是一个AI agent(智能体),也是开源的应用程序,结合了GPT-4和GPT-3.5技术,给定自然语言的目标,它将尝试通过将其分解成子任务,并在自动循环中使用互联网和其他工具来实现这一目标

ninja: Entering directory `out/build' [11654/104961] ACTION //build/android:build_java__validate(//build/toolchain/android:android_clang_arm) FAILED: obj/build/android/build_java__validate.bytecode.stamp python3 ../../build/android/gyp/check_for_missing_direct_deps.py --depfile gen/build/android/build_java__validate.d --target-name //build/android:build_java__validate --gn-target=//build/android:build_java --input-jar obj/build/android/build_java.javac.jar --stamp obj/build/android/build_java__validate.bytecode.stamp --chromium-output-dir . --direct-classpath-jars=@FileArg\(gen/build/android/build_java.build_config.json:interface_classpath\) --full-classpath-jars=@FileArg\(gen/build/android/build_java.build_config.json:javac_full_interface_classpath\) --full-classpath-gn-targets=@FileArg\(gen/build/android/build_java.build_config.json:javac_full_classpath_targets\) --direct-classpath-jars=obj/build/android/build_java.turbine.jar --use-build-server --warnings-as-errors Traceback (most recent call last): File "/home/holand/work/webrtc/android/src/out/build/../../build/android/gyp/check_for_missing_direct_deps.py", line 303, in <module> sys.exit(main(sys.argv)) File "/home/holand/work/webrtc/android/src/out/build/../../build/android/gyp/check_for_missing_direct_deps.py", line 279, in main if server_utils.MaybeRunCommand(name=args.target_name, File "/home/holand/work/webrtc/android/src/build/android/gyp/util/server_utils.py", line 54, in MaybeRunCommand raise Exception( Exception: AUTONINJA_BUILD_ID is not set. android_static_analysis = build_server requires autoninja integration. [11675/104961] CXX obj/ipc/ipc/ipc_channel_mojo.o ninja: build stopped: subcommand failed.
最新发布
08-13
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值