使用 gradle 构建库项目时,BuildConfig.DEBUG 总是错误的

在调试模式下运行应用程序时,BuildConfig.DEBUG 无法工作(= 逻辑设置为 false)。 我用 Gradle 来建造。我有一个图书馆的项目,我做这个检查。在构建调试文件夹中,BuildConfig.java 如下所示:

/** Automatically generated the file. DO NOT MODIFY */
package common.myProject;


public final class BuildConfig {
public static final boolean DEBUG = Boolean.parseBoolean("true");


}

在发布文件夹中:

public static final boolean DEBUG = false;

在图书馆项目和应用项目中。

我试图通过检查一个变量来解决这个问题,这个变量设置了我的项目的一个类。此类从库继承并启动。

<application
android:name=".MyPrj" ...

这导致了另一个问题: 我在运行在应用程序类之前的 DataBaseProvider 中使用了 DEBUG 变量,由于这个 bug,它将无法正常运行。

42746 次浏览

这是预期的行为。

库项目只发布它们的版本变体,供其他项目或模块使用。

我们正在努力解决这个问题,但是这个问题不容小觑,需要大量的工作。

您可以在 https://code.google.com/p/android/issues/detail?id=52962跟踪问题

您可以在每个 buildType 项目上尝试这种方法:

parent.allprojects.each{ project -> android.defaultConfig.debuggable = true}

作为解决方案,您可以使用这个方法,它使用反射从应用程序(而不是库)获取字段值:

/**
* Gets a field from the project's BuildConfig. This is useful when, for example, flavors
* are used at the project level to set custom fields.
* @param context       Used to find the correct file
* @param fieldName     The name of the field-to-access
* @return              The value of the field, or {@code null} if the field is not found.
*/
public static Object getBuildConfigValue(Context context, String fieldName) {
try {
Class<?> clazz = Class.forName(context.getPackageName() + ".BuildConfig");
Field field = clazz.getField(fieldName);
return field.get(null);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}

例如,要获取 DEBUG字段,只需从 Activity调用:

boolean debug = (Boolean) getBuildConfigValue(this, "DEBUG");

我也在 AOSP 问题追踪器上分享了这个解决方案。

可以使用 gradle 为每种生成类型创建自己的 BuildConfig 类

public class MyBuildConfig
{
public static final boolean DEBUG = true;
}

/src/debug/.../MyBuildConfig.java和..。

public class MyBuildConfig
{
public static final boolean DEBUG = false;
}

/src/release/.../MyBuildConfig.java

然后使用:

if (MyBuildConfig.DEBUG)
Log.d(TAG, "Hey! This is debug version!");

我们遇到了同样的问题,我想到了这个:

我们有一个 SDK (库)和一个演示项目,层次结构如下:

Parent
|
+ SDK (:SDK)
|
+ DemoApp (:DemoApp)

对于我们的演示应用程序,如果 :SDK:jarjarDebug:SDK:jarjarRelease:SDK的一些特定任务,产生一些后处理的罐子:

dependencies {
debugCompile tasks.getByPath(":SDK:jarjarDebug").outputs.files
releaseCompile tasks.getByPath(":SDK:jarjarRelease").outputs.files
... more dependencies ...
}

这甚至适用于同时构建多个 buildTypes。不过调试有点困难。请注释。

这就像菲尔的回答,只不过不需要上下文:

private static Boolean sDebug;


/**
* Is {@link BuildConfig#DEBUG} still broken for library projects? If so, use this.</p>
*
* See: https://code.google.com/p/android/issues/detail?id=52962</p>
*
* @return {@code true} if this is a debug build, {@code false} if it is a production build.
*/
public static boolean isDebugBuild() {
if (sDebug == null) {
try {
final Class<?> activityThread = Class.forName("android.app.ActivityThread");
final Method currentPackage = activityThread.getMethod("currentPackageName");
final String packageName = (String) currentPackage.invoke(null, (Object[]) null);
final Class<?> buildConfig = Class.forName(packageName + ".BuildConfig");
final Field DEBUG = buildConfig.getField("DEBUG");
DEBUG.setAccessible(true);
sDebug = DEBUG.getBoolean(null);
} catch (final Throwable t) {
final String message = t.getMessage();
if (message != null && message.contains("BuildConfig")) {
// Proguard obfuscated build. Most likely a production build.
sDebug = false;
} else {
sDebug = BuildConfig.DEBUG;
}
}
}
return sDebug;
}

使用 Android Studio 1.1,并且拥有1.1的 gradle 版本,这是可能的:

图书馆

android {
publishNonDefault true
}

应用程序

dependencies {
releaseCompile project(path: ':library', configuration: 'release')
debugCompile project(path: ':library', configuration: 'debug')
}

完整的文档可以在这里找到 http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Library-Publication

编辑:

问题刚刚被标记为固定的 Android 工作室等级版本3.0。在那里,您可以只使用 implementation project(path: ':library'),它会自动选择正确的配置。

还有一个办法。

1)创建一个界面

public interface BuildVariantDetector {


boolean isDebugVariant();


}

2)在应用程序类(应用程序模块)上使用此接口

public class MyApplication extends Application implements BuildVariantDetector {


@Override
public boolean isDebugVariant() {
return BuildConfig.DEBUG; //application (main module) Buildonfig
}


}

3) 然后在图书馆模块中:

boolean debugVariant = ((BuildVariantDetector)getApplication()).isDebugVariant();

这并不是检查你是否处于调试状态的正确方法,但你可以通过以下方式检查应用程序本身是否可调试:

private static Boolean sIsDebuggable;


public static boolean isDebuggable(Context context) {
if (sIsDebuggable == null)
sIsDebuggable = (context.getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
return sIsDebuggable;
}

应用程序和库的默认行为将与之完美匹配。

如果你需要一个更好的解决方案,你可以使用以下方法:

public static boolean isInDebugFlavour(Context context) {
if (sDebugFlavour == null) {
try {
final String packageName = context.getPackageName();
final Class<?> buildConfig = Class.forName(packageName + ".BuildConfig");
final Field DEBUG = buildConfig.getField("DEBUG");
DEBUG.setAccessible(true);
sDebugFlavour = DEBUG.getBoolean(null);
} catch (final Throwable t) {
sDebugFlavour = false;
}
}
return sDebugFlavour;
}

检查 imports,有时无意中从任何类库导入 BuildConfig。 例如:

import io.fabric.sdk.android.BuildConfig;

在这种情况下,BuildConfig.DEBUG总是返回 假的;

import com.yourpackagename.BuildConfig;

在这种情况下,BuildConfig.DEBUG将返回真正的 构建变体。

在我的例子中,我导入了错误的 BuildConfig,因为我的项目有许多库模块。补丁是为我的 app模块导入正确的 BuildConfig

这是我的变通方案: 反映应用程序模块的 BuildConfig:

Public static boolean debug = isDebug () ;

private static boolean isDebug() {
boolean result = false;
try {
Class c = Class.forName("com.example.app.BuildConfig");
Field f = c.getField("DEBUG");
f.setAccessible(true);
result = f.getBoolean(c);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return result;
}`

在分级文件中使用可调试 true。

buildTypes {
demo{
debuggable true
}
live{
debuggable true
}
}

DEBUG 根本不可靠,Android 提供了一个全局可用的内部标志,指示构建是处于调试模式还是非调试模式

(getContext().getApplicationInfo().flags &ApplicationInfo.FLAG_DEBUGGABLE) != 0)

将是真实的,如果它是在调试

来源: https://medium.com/@elye.project/checking-debug-build-the-right-way-d12da1098120