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, которая запускается перед классом приложения, и она не будет работать должным образом из-за этой ошибки.
android
gradle
android-library
user1324936
источник
источник
Ответы:
Это ожидаемое поведение для этого.
Проекты библиотеки публикуют только свои варианты выпуска для использования другими проектами или модулями.
Мы работаем над исправлением этого, но это нетривиально и требует значительного объема работы.
Вы можете отслеживать проблему на странице https://code.google.com/p/android/issues/detail?id=52962.
источник
С 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
ИЗМЕНИТЬ :
Вопрос только что был отмечен как фиксированный для Android Studio Gradle версии 3.0. Там вы можете просто использовать,
implementation project(path: ':library')
и он автоматически выберет правильную конфигурацию.источник
Проверьте
imports
, иногда BuildConfig случайно импортируется из любого класса библиотеки. Например:import io.fabric.sdk.android.BuildConfig;
В этом случае BuildConfig.DEBUG всегда будет возвращать false ;
import com.yourpackagename.BuildConfig;
В этом случае BuildConfig.DEBUG вернет ваш реальный вариант сборки.
источник
Это похоже на ответ Фила, за исключением того, что ему не нужен контекст:
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; }
источник
В качестве обходного пути вы можете использовать этот метод, который использует отражение для получения значения поля из приложения (а не из библиотеки):
/** * 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 .
источник
applicationIdSuffix
в Gradle, которое сделает.BuildConfig
класс недоступным из этого кода выше.Не совсем правильный способ проверить, используете ли вы отладочную версию, но вы можете проверить, можно ли отладить само приложение с помощью:
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; }
источник
Вы можете создать свой собственный класс 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!");
источник
Вот еще одно решение.
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();
источник
У нас была такая же проблема. Я придумал что-то вроде этого:
У нас есть SDK (библиотека) и демонстрационный проект, иерархия выглядит так:
Parent | + SDK (:SDK) | + DemoApp (:DemoApp)
Для демонстрационного приложения, которое у нас есть, были
:SDK:jarjarDebug
и:SDK:jarjarRelease
есть некоторые конкретные задачи для:SDK
создания некоторых постобработанных jar-файлов:dependencies { debugCompile tasks.getByPath(":SDK:jarjarDebug").outputs.files releaseCompile tasks.getByPath(":SDK:jarjarRelease").outputs.files ... more dependencies ... }
Это работает даже для нескольких
buildTypes
построенных одновременно. Однако отладка немного сложна. Прокомментируйте, пожалуйста.источник
Это мой обходной путь: отразите 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; }`
источник
Вы можете попробовать это в каждом из проектов buildTypes:
parent.allprojects.each{ project -> android.defaultConfig.debuggable = true}
источник
buildType
конфигурацию сборки, а не в ее. Теоретически настройка подписи отладки должна сделать тот же трюкВ моем случае я неправильно импортировал, так
BuildConfig
как в моем проекте много библиотечных модулей. Исправление заключалось в том, чтобы импортировать правильныйBuildConfig
для моегоapp
модуля.источник
Работа с debuggable true в файле gradle.
buildTypes { demo{ debuggable true } live{ debuggable true } }
источник
BuildConfig.DEBUG вообще ненадежен, Android предоставил внутренний флаг, который доступен во всем мире, указывая, находится ли сборка в режиме отладки или без нее.
(getContext().getApplicationInfo().flags &ApplicationInfo.FLAG_DEBUGGABLE) != 0)
будет правдой, если он находится в отладке
Кредиты: https://medium.com/@elye.project/checking-debug-build-the-right-way-d12da1098120
источник