BuildConfig.DEBUG всегда false при создании проектов библиотеки с помощью gradle
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" ...
Это приводит к другой проблеме: я использую переменную DEBUG в DataBaseProvider, который запускается перед классом приложения, и он не будет работать должным образом из-за этой ошибки.
Ответы
Ответ 1
Это ожидаемое поведение для этого.
Библиотечные проекты публикуют только свои варианты выпуска для потребления другими проектами или модулями.
Мы работаем над исправлением этого, но это нетривиально и требует значительного количества работы.
Вы можете отслеживать проблему на https://code.google.com/p/android/issues/detail?id=52962
Ответ 2
С Android Studio 1.1 и с версией gradle в версии 1.1 можно:
Библиотека
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
ИЗМЕНИТЬ
issue только что был отмечен как исправленный для Android Studio gradle Version 3.0. Там вы можете просто использовать implementation project(path: ':library')
, и он автоматически выберет правильную конфигурацию.
Ответ 3
Проверить imports
, иногда BuildConfig импортируется из любого класса библиотеки непреднамеренно.
Например:
import io.fabric.sdk.android.BuildConfig;
В этом случае BuildConfig.DEBUG всегда будет возвращать false;
import com.yourpackagename.BuildConfig;
В этом случае BuildConfig.DEBUG вернет ваш реальный вариант .
Ответ 4
Это похоже на ответ Фила, за исключением того, что контекст не нужен:
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;
}
Ответ 5
В качестве обходного пути вы можете использовать этот метод, который использует отражение для получения значения поля из приложения (а не библиотеки):
/**
* Gets a field from the project 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 Issue Tracker.
Ответ 6
Не совсем правильный способ проверить, есть ли у вас отладочный вкус, но вы можете проверить, действительно ли приложение отлаживается с помощью:
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;
}
Ответ 7
Вы можете создать свой собственный класс BuildConfig для каждого типа сборки, используя gradle
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!");
Ответ 8
Вот еще одно решение.
1) Создайте интерфейс
public interface BuildVariantDetector {
boolean isDebugVariant();
}
2) Используйте этот интерфейс для класса Application (модуль Appplication)
public class MyApplication extends Application implements BuildVariantDetector {
@Override
public boolean isDebugVariant() {
return BuildConfig.DEBUG; //application (main module) Buildonfig
}
}
3)
А затем в библиотечном модуле:
boolean debugVariant = ((BuildVariantDetector)getApplication()).isDebugVariant();
Ответ 9
У нас была та же проблема. Я придумал что-то вроде этого:
У нас есть 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
, созданных за один раз. Отладка немного сложная. Прокомментируйте.
Ответ 10
Это мое обходное решение:
отразить 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;
}`
Ответ 11
Вы можете попробовать это на каждом из проектов buildTypes:
parent.allprojects.each{ project -> android.defaultConfig.debuggable = true}
Ответ 12
В моем случае я импортировал неправильный BuildConfig
, так как у моего проекта много библиотечных модулей. Исправлено было импортирование правильного BuildConfig
для моего модуля app
.
Ответ 13
Работа с отладочной истиной в файле Gradle.
buildTypes {
demo{
debuggable true
}
live{
debuggable true
}
}
Ответ 14
BuildConfig.DEBUG вообще не является надежным, Android предоставил глобальный внутренний флаг, указывающий, находится ли сборка в режиме отладки или без отладки
(getContext().getApplicationInfo().flags &ApplicationInfo.FLAG_DEBUGGABLE) != 0)
будет верно, если это в отладке
Кредиты: https://medium.com/@elye.project/checking-debug-build-the-right-way-d12da1098120