Когда ADT устанавливает для BuildConfig.DEBUG значение false?


110

В последней версии ADT (r17) была добавлена ​​сгенерированная константа, BuildConfig.DEBUGкоторая устанавливается в соответствии с типом сборки. У меня проблема в том, что для него никогда не устанавливается значение false, я ожидал, что это изменится при выполнении «Android Tools -> Export Signed Application Package», но это не для меня.

Итак, как мне изменить тип сборки?

Добавлена ​​функция, позволяющая запускать некоторый код только в режиме отладки. Сборки теперь создают класс с именем BuildConfig, содержащий константу DEBUG, которая автоматически устанавливается в соответствии с типом сборки. Вы можете проверить константу (BuildConfig.DEBUG) в своем коде, чтобы запускать функции только для отладки


2
BuildConfig.java автоматически создается инструментами сборки Android и помещается в папку gen. Подписанный APK должен иметь BuildConfig.DEBUG = false. Для тебя это не должно быть проблемой. Вам не нужно вручную трогать этот файл ...
Игорь Ганапольский

1
Если вы используете gradle для выпуска этого флага, он будет надежным на 100%. Итак, когда вы выполняете ./gradlew AssemblyDebug, это true, а при выполнении AssemblyRelease - false.
slott

Ответы:


56

В настоящее время вы можете добиться правильного поведения, отключив «Автоматическая сборка», очистив проект и затем экспортируя его через «Инструменты Android -> Экспорт подписанного пакета приложения». При запуске приложение BuildConfig.DEBUGдолжно быть ложным.


тоже сломан. Следствием этого является отображение всех сообщений Log.d, которые следует опустить с помощью этого флага. пс. куда подавать отчет об ошибке?
tomi

у меня всегда ложно, даже при отладке
behelit

39

В Eclipse я всегда отключаю параметр «Создавать автоматически» перед экспортом приложения в выпуске. Потом чищу проект и экспортирую. В противном случае он начинает компиляцию в режиме отладки, и тогда значение BuildConfig.DEBUG может быть неправильным.

В Android Studio я просто добавляю свою собственную переменную в build.gradle:

buildTypes {
    debug {
        buildConfigField "Boolean", "DEBUG_MODE", "true"
    }
    release {
        buildConfigField "Boolean", "DEBUG_MODE", "false"
    }
}

Когда я создаю проект, BuildConfig.java создается следующим образом:

public final class BuildConfig {
  // Fields from build type: debug
  public static final Boolean DEBUG_MODE = true;
}

Затем в моем коде я могу использовать:

if (BuildConfig.DEBUG_MODE) {
    // do something
}

Я рекомендую очистить после переключения сборки отладки / выпуска.


1
Это решение является лучшим, если вы используете proguard, потому что он будет генерировать константу с буквальным значением, поэтому ваш код отладки будет полностью удален из двоичного файла в режиме выпуска.
Виктор Лаэрт

33

Не работает должным образом:

Проблема 27940 : BuildConfig.DEBUG имеет значение "true" для экспортированного пакета приложения.

Жаль, что они иногда выпускают глючные функции.


9
Перейдите по ссылке на проблему, упомянутую выше, и отметьте ее звездочкой, если вы хотите, чтобы это было исправлено.
Guy

11

Это работает, но обратите внимание, что файл кода никогда не изменяется, даже при экспорте подписанного файла. В процессе экспорта значение этой переменной изменяется на false, что может создать ложное впечатление, что она не работает. Я тестировал это с помощью таких операторов регистрации, как

if (com.mypackage.BuildConfig.DEBUG)
            Log.d(TAG, location.getProvider() + " location changed");

При тестировании мои операторы журнала больше не производят никакого вывода.


1
Что именно ты сделал?
pbhowmick

2
Я изменил экземпляры BuildConfig.DEBUG на com.mypackage.BuildConfig.DEBUG, затем перезапустил приложение ... и оно все время возвращало true. Может я неправильно понял ваше предложение.
Крис Рэй,

1
Я говорю, что код НЕ изменится. Однако для com.mypackage.BuildConfig.DEBUG будет установлено значение False post compilation. Попробуйте выполнить тестовый оператор ведения журнала, как указано выше (выберите произвольную строку для журнала), выполните экспорт, а затем запустите его. Посмотрите, отображает ли adb оператор регистрации. Я сделаю ставку на то, что adb не будет сообщать об этом операторе регистрации, означающем, что для DEUBUG установлено значение false.
pbhowmick

1
Я не уверен, что понимаю, что вы имеете в виду, говоря о «коде» ... однако я скажу, что очистка перед экспортом APK (как предлагается в принятом ответе) сделала как BuildConfig.DEBUG, так и com.mypackage.BuildConfig .DEBUG сообщает false, как и ожидалось.
Chris Rae

Ты понял. Это ожидаемое поведение.
pbhowmick

10

Проверьте imports, иногда BuildConfig случайно импортируется из любого класса библиотеки. Например:

import io.fabric.sdk.android.BuildConfig;

В этом случае BuildConfig.DEBUG всегда будет возвращать false ;

import com.yourpackagename.BuildConfig;

В этом случае BuildConfig.DEBUG вернет ваш реальный вариант сборки .

ps Я просто копирую это из своего ответа здесь: BuildConfig.DEBUG всегда ложно при создании проектов библиотеки с помощью gradle


1
Ага, для меня это случайно завезено из android.support.compat. Я думаю, это еще одна причина просто определить свое собственное поле с другим именем.
arekolek

5

Из раздела "Подготовка к выпуску" :

Отключить ведение журнала и отладку

Обязательно отключите ведение журнала и отключите параметр отладки, прежде чем создавать приложение для выпуска. Вы можете отключить ведение журнала, удалив вызовы методов журнала в исходных файлах. Вы можете отключить отладку, удалив атрибут android: debuggable из тега в файле манифеста или установив для атрибута android: debuggable значение false в файле манифеста. Кроме того, удалите все файлы журналов или файлы статических тестов, которые были созданы в вашем проекте.

Кроме того, вам следует удалить все вызовы трассировки отладки, которые вы добавили в свой код, такие как вызовы методов startMethodTracing () и stopMethodTracing ().

Больше информации по ссылке.


1
Я думал, что этот процесс теперь происходит автоматически во время сборки: developer.android.com/tools/sdk/tools-notes.html
Игорь Ганапольский

Вызывает ошибку времени компиляции: «Избегайте жесткого кодирования режима отладки; если его не
указывать,

5

Решение для меня:

  1. Проект -> Создавать автоматически
  2. Проект -> Очистить
  3. Проект -> Сборка
  4. Приложение Project Export для Android

Это работа в r20


1
Это сработало для меня только сейчас (я думаю, используя последнюю версию ADT). Может, чистка исправила, не уверен.
Джонни

3

Я хотел бы предложить простой обходной путь, если вы используете proguard во время экспорта APK.

Proguard предоставляет способ удалить вызовы определенных функций в режиме выпуска. Любые вызовы журналов отладки можно удалить с помощью следующих настроек в proguard-project.txt.

# Remove debug logs
-assumenosideeffects class android.util.Log {
    public static *** d(...);
    public static *** v(...);
}

И настройка оптимизации project.properties.

proguard.config=${sdk.dir}/tools/proguard/proguard-android-optimize.txt:proguard-project.txt

При этом вам не нужно беспокоиться о каких-либо ненужных вычислениях String, передаваемых в журнал отладки, на который указал @Jeremyfa. Вычисления просто удаляются в сборке релиза.

Таким образом, обходной путь для BuildConfig.DEBUG использует ту же функцию proguard, как показано ниже.

public class DebugConfig {

    private static boolean debug = false;

    static {
        setDebug(); // This line will be removed by proguard in release.
    }

    private static void setDebug() {
        debug = true;
    }

    public static boolean isDebug() {
        return debug;
    }
}

И после установки в proguard-project.txt.

-assumenosideeffects class com.neofect.rapael.client.DebugConfig {
    private static *** setDebug();
}

Я бы предпочел использовать это, чтобы отключить эту Build Automaticallyопцию, потому что это не зависит от индивидуальных настроек IDE конструктора, а сохраняется как зафиксированный файл, который совместно используется разработчиками.


1

Не работает, насколько я понял ( проблема Android 22241 )

У меня были проблемы с проектом (при работе с Eclipse), эта константа не была установлена ​​в значение true при экспорте подписанного APK моего проекта :(

Хотел бы услышать, что это работает, хотя


1
Это должно было быть исправлено в r17, оно было отмечено как таковое в системе отслеживания ошибок.
smith324

1
На самом деле библиотеки не компилируются в режиме выпуска в ADT при экспорте (работает в Ant). Я обновил code.google.com/p/android/issues/detail?id=27940
Xavier Ducrohet,

1
@Xav, спасибо, что изучили это, я перестану спамить вам, обещаю. На самом деле это был основной проект, с которым у меня возникли проблемы (не смотрел на зависимую библиотеку). Если я смогу создать конкретный тестовый пример, я опубликую его в системе отслеживания ошибок с той же проблемой.
smith324,

1

хороший способ - создать свой собственный класс:

public class Log {

public static void d(String message) {
    if (BuildConfig.DEBUG)
        android.util.Log.d(
            "[" + (new Exception().getStackTrace()[1].getClassName()) + "]",
            "{" + (new Exception().getStackTrace()[1].getMethodName()) + "} "
            + message
        );
}

}

12
Проблема с этим методом заключается в том, что событие, когда DEBUG имеет значение false, java по-прежнему будет вычислять каждую строку, чтобы передать ее вашему пользовательскому классу. If (DEBUG) Log.d (...) менее элегантен, но более эффективен.
Jeremyfa

0

Я видел странное поведение, связанное с тем, что значения в BuildConfig установлены на их окончательные значения. Возможно, это связано с вашей проблемой.

Простое объяснение состоит в том, что значения по умолчанию устанавливаются изначально до запуска Proguard, а затем после запуска Proguard файл BuildConfig восстанавливается с правильными значениями. Однако Proguard к этому моменту уже оптимизировал ваш код, и у вас есть проблемы.

Вот ошибка, которую я создал против Gradle. https://code.google.com/p/android/issues/detail?id=182449

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.