在Android开发中,通常会有Debug和Release环境,比如:Debug环境用测试接口,Release环境用正式接口;Debug环境打印Log,Release环境不打印Log等等。
BuildConfig文件是项目编译后自动生成的,它存在于module的
\build\generated\source\buildConfig文件夹下面:
其实BuildConfig文件是一个java类,在debug中是这样的:
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.wj.study;
public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");
public static final String APPLICATION_ID = "com.wj.study";
public static final String BUILD_TYPE = "debug";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
}
在release中是这样的:
/**
* Automatically generated file. DO NOT MODIFY
*/
package com.wj.study;
public final class BuildConfig {
public static final boolean DEBUG = false;
public static final String APPLICATION_ID = "com.wj.study";
public static final String BUILD_TYPE = "release";
public static final String FLAVOR = "";
public static final int VERSION_CODE = 1;
public static final String VERSION_NAME = "1.0";
}
默认有六个参数,其中boolean值的DEBUG参数标志了debug包与release包的区别。在debug包中DEBUG=true,release包中DEBUG=false。
那么,在module中就可以通过BuildConfig.DEBUG的值来区分debug和release。
当然,如果要添加额外的参数来区分debug和release也是可以的,在module的build.gradle文件中添加:
buildTypes {
debug {
buildConfigField "Boolean", "DEBUG_MODE", "true"
}
release {
buildConfigField "Boolean", "DEBUG_MODE", "false"
}
}
编译后,在debug的BuildConfig.java中会自动添加一行:
// Fields from build type: debug
public static final Boolean DEBUG_MODE = false;
在Release的BuildConfig.java中也会自动添加一行:
// Fields from build type: release
public static final Boolean DEBUG_MODE = true;
那么也就可以用BuildConfig.DEBUG_MODE来区分。
从上面可以看出,编译自动生成的BuildConfig文件可以区分debug和release包,但如果在项目中有多个module(通常有很多个module),每个module都会生成自己的BuildConfig文件,那么就需要每个module自己各行处理debug和release的区别。这样就导致不统一,比如打开和关闭打印Log,就得各自管理。
现在在项目的非主module “Lib module base”中建立一个打印Log的类LogUtil:
public class LogUtil {
private final static boolean DEBUG = BuildConfig.DEBUG;
public static void d(String tag, String msg) {
Log.d(tag, "d-->DEBUG=" + DEBUG);
if (DEBUG) {
Log.d(tag, msg);
}
}
}
再在主module中引用这个LogUtil类,从实际的测试结果上看,无论是debug包还是release包,结果LogUtil.DEBUG的值都是false。因为编译时被依赖的 module 默认会提供 Release 版给其它module 或工程使用,这就导致该 BuildConfig.DEBUG 会始终为 false。
接下来用Application的FLAG_DEBUGGABLE来解决这个问题。
元素application有一个属性debuggable,在debug构建的时候会设置成false,在release构建的时候会设置成ture。这些都是自动设置,并不需要在元素application中设置android:debuggable=”false|true”。
所以可以这样写:
public static void init(Context context) {
DEBUG = context.getApplicationInfo() != null &&
(context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
}
但在调用的时候要在Application的onCreate方法中调用:
public class Study extends Application {
@Override
public void onCreate() {
super.onCreate();
LogUtil.init(getApplicationContext());
}
}
因此,这就可以判断debug包和release包了。
参考:
Android Debug 版本判断及为什么 BuildConfig.DEBUG 始终为 false