Kiedy narzędzie ADT ustawia wartość BuildConfig.DEBUG na false?

110

W najnowszej wersji ADT (r17) dodano wygenerowaną stałą, BuildConfig.DEBUGktóra jest ustawiana zgodnie z typem kompilacji. Problem polega na tym, że nigdy nie jest ustawiony na false, spodziewałem się, że zmieni się podczas wykonywania „Narzędzia Android -> Eksportuj podpisany pakiet aplikacji”, ale tak się nie stało.

Jak więc zmienić typ kompilacji?

Dodano funkcję, która umożliwia uruchamianie części kodu tylko w trybie debugowania. Kompilacje generują teraz klasę o nazwie BuildConfig zawierającą stałą DEBUG, która jest automatycznie ustawiana zgodnie z typem kompilacji. Możesz sprawdzić stałą (BuildConfig.DEBUG) w kodzie, aby uruchomić funkcje tylko do debugowania

smith324
źródło
2
BuildConfig.java jest generowany automatycznie przez narzędzia do budowania systemu Android i umieszczany w folderze gen. Podpisany plik APK powinien mieć BuildConfig.DEBUG = false. Nie powinno to stanowić dla ciebie problemu. Nie powinieneś ręcznie dotykać tego pliku ...
Igor Ganapolsky
1
Jeśli używasz gradle do zwolnienia tej flagi, jest to w 100% wiarygodne. Więc kiedy robisz ./gradlew assembleDebug to prawda, a kiedy robisz assembleRelease to fałsz.
szczelina

Odpowiedzi:

56

Obecnie można uzyskać poprawne zachowanie, wyłączając opcję „Buduj automatycznie”, czyszcząc projekt, a następnie eksportując za pomocą opcji „Narzędzia systemu Android -> Eksportuj podpisany pakiet aplikacji”. Po uruchomieniu aplikacja BuildConfig.DEBUGpowinna być fałszywa.

smith324
źródło
zepsuty też. Powoduje to wyświetlenie wszystkich komunikatów Log.d, które powinny być pomijane przez tę flagę. ps. gdzie zgłosić błąd?
tomi
mój jest zawsze fałszywy, nawet podczas debugowania
behelit
39

W Eclipse zawsze wyłączam opcję „Buduj automatycznie” przed wyeksportowaniem aplikacji w wersji. Następnie czyszczę projekt i eksportuję. W przeciwnym razie rozpocznie kompilację w trybie debugowania, a następnie wartość BuildConfig.DEBUG może być nieprawidłowa.

W Android Studio po prostu dodaję własną zmienną niestandardową w pliku build.gradle:

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

Kiedy buduję projekt, BuildConfig.java jest generowany w następujący sposób:

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

Następnie w swoim kodzie mogę użyć:

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

Polecam wyczyścić po przełączeniu kompilacji debugowania / wydania.

Arnaud SmartFun
źródło
1
To rozwiązanie jest najlepsze, jeśli używasz programu proguard, ponieważ wygeneruje stałą z wartością literału, więc kod debugowania zostanie całkowicie usunięty z pliku binarnego w trybie wydania.
Victor Laerte
33

Nie działa poprawnie:

Problem 27940 : BuildConfig.DEBUG ma wartość „prawda” dla wyeksportowanego pakietu aplikacji

To rozczarowujące, że czasami wypuszczają błędne funkcje.

Randy Sugianto „Yuku”
źródło
9
Przejdź do linku do powyższego problemu i oznacz go gwiazdką, jeśli chcesz, aby problem został rozwiązany.
Guy
11

Działa, ale pamiętaj, że plik kodu nigdy się nie zmienia, nawet podczas eksportowania podpisanego pliku. Eksport proces zmienia wartość tej zmiennej na FALSE, co może dać fałszywe wrażenie, że to nie działa. Przetestowałem to z instrukcjami logowania, takimi jak

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

Podczas testowania moje instrukcje Log nie generują już żadnych danych wyjściowych.

pbhowmick
źródło
1
Co dokładnie zrobiłeś?
pbhowmick
2
Zmieniłem wystąpienia BuildConfig.DEBUG na com.mypackage.BuildConfig.DEBUG, a następnie ponownie uruchomiłem aplikację ... i nadal zwracała prawdę przez cały czas. Może źle zrozumiałem twoją sugestię.
Chris Rae,
1
Mówię o tym, że kod NIE ulegnie zmianie. Jednak com.mypackage.BuildConfig.DEBUG zostanie ustawiony na fałszywą kompilację po zakończeniu. Wypróbuj instrukcję rejestrowania testu, jak powyżej (wybierz dowolny ciąg do zarejestrowania), wyeksportuj, a następnie uruchom. Sprawdź, czy adb wyświetla instrukcję rejestrowania. Jestem gotów założyć się, że adb nie zgłosi tego protokołu logowania, co oznacza, że ​​DEUBUG został ustawiony na fałsz.
pbhowmick
1
Nie jestem pewien, czy wiem, co masz na myśli mówiąc o „kodzie” ... jednak powiem, że wyczyszczenie pliku przed wyeksportowaniem pliku APK (zgodnie z sugestią zawartą w zaakceptowanej odpowiedzi) spowodowało, że zarówno BuildConfig.DEBUG, jak i com.mypackage.BuildConfig .DEBUG raport jest fałszywy, zgodnie z oczekiwaniami.
Chris Rae
Masz to. To jest oczekiwane zachowanie.
pbhowmick
10

Sprawdź imports, czy czasami BuildConfig jest importowany z dowolnej klasy biblioteki. Na przykład:

import io.fabric.sdk.android.BuildConfig;

W tym przypadku BuildConfig.DEBUG zawsze zwróci false ;

import com.yourpackagename.BuildConfig;

W tym przypadku BuildConfig.DEBUG zwróci Twój prawdziwy wariant kompilacji .

ps Po prostu skopiowałem ten z mojej odpowiedzi tutaj: BuildConfig.DEBUG zawsze fałsz podczas budowania projektów biblioteki za pomocą gradle

Gent Berani
źródło
1
Tak, dla mnie został przypadkowo zaimportowany z android.support.compat. Myślę, że to kolejny powód, aby po prostu zdefiniować własne pole pod inną nazwą.
arekolek
5

Od przygotowania do wydania :

Wyłącz rejestrowanie i debugowanie

Pamiętaj, aby dezaktywować rejestrowanie i opcję debugowania przed utworzeniem aplikacji do wydania. Możesz wyłączyć rejestrowanie, usuwając wywołania metod logowania w plikach źródłowych. Możesz wyłączyć debugowanie, usuwając atrybut android: debuggable z tagu w pliku manifestu lub ustawiając atrybut android: debuggable na false w pliku manifestu. Usuń również wszystkie pliki dziennika lub statyczne pliki testowe, które zostały utworzone w projekcie.

Należy również usunąć wszystkie wywołania śledzenia debugowania, które zostały dodane do kodu, takie jak wywołania metod startMethodTracing () i stopMethodTracing ().

Więcej informacji znajduje się pod linkiem.

Piotr
źródło
1
Myślałem, że ten proces odbywa się teraz automatycznie w czasie kompilacji: developer.android.com/tools/sdk/tools-notes.html
IgorGanapolsky
Powoduje błąd w czasie kompilacji: «Unikaj twardego kodowania trybu debugowania; opuszczenie go pozwala debugować i wydać kompilacje na automatyczne przypisanie jednego »
Nikita Bosik,
5

Rozwiązanie dla mnie:

  1. Projekt -> Buduj automatycznie
  2. Projekt -> Wyczyść
  3. Projekt -> Kompiluj
  4. Aplikacja Project Export na Androida

Działa w r20

e.shishkin
źródło
1
To zadziałało dla mnie właśnie teraz (przy użyciu najnowszego ADT). Może sprzątanie to naprawiło, nie jestem pewien.
Jonny
3

Chciałbym zaproponować proste obejście, jeśli używasz proguard podczas eksportu APK.

Proguard zapewnia sposób usuwania wywołań określonych funkcji w trybie wydania. Wszelkie wywołania dzienników debugowania można usunąć za pomocą następującego ustawienia w proguard-project.txt.

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

I ustawianie optymalizacji project.properties.

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

Dzięki temu nie musisz przejmować się niepotrzebnym przekazywaniem obliczeń String do dziennika debugowania, na który wskazywał @Jeremyfa. Obliczenia zostały właśnie usunięte w kompilacji wydania.

Tak więc obejście dla BuildConfig.DEBUG używa tej samej funkcji proguard, co śledzenie.

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;
    }
}

I po ustawieniu proguard-project.txt.

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

Wolałbym używać tego Build Automaticallyzamiast wyłączać opcję, ponieważ nie zależy to od indywidualnych ustawień IDE konstruktora, ale jest utrzymywane jako zatwierdzony plik, który jest współdzielony przez programistów.

neo.kim
źródło
1

O ile zrozumiałem, nie działa poprawnie ( numer 22241 )

Miałem problemy z projektem (praca z Eclipse), ta stała nie była ustawiona na true podczas eksportowania podpisanego pliku APK mojego projektu :(

Chciałbym usłyszeć, że to działa

Vincent Mimoun-Prat
źródło
1
Powinien zostać naprawiony w r17, jako taki oznaczono w narzędziu do śledzenia błędów.
smith324
1
W rzeczywistości biblioteki nie są kompilowane w trybie wydania w ADT podczas eksportu (działa w Ant). Zaktualizowałem code.google.com/p/android/issues/detail?id=27940
Xavier Ducrohet
1
@Xav dzięki za przyjrzenie się temu, przestanę spamować, obiecuję. To był właściwie główny projekt, z którym miałem problemy (nie patrzyłem na bibliotekę zależną). Jeśli uda mi się stworzyć konkretny przypadek testowy, wyślę go do modułu śledzenia błędów w ramach tego samego problemu.
smith324
1

dobrym sposobem jest stworzenie własnej klasy:

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
        );
}

}
Bouchehboun Saad
źródło
12
Problem z tą metodą polega na tym, że zdarzenie, gdy DEBUG ma wartość false, java nadal będzie obliczać każdy ciąg znaków, aby przekazać go do niestandardowej klasy. Jeśli (DEBUG) Log.d (...) jest mniej elegancki, ale bardziej wydajny.
Jeremyfa
0

Widziałem dziwne zachowanie, które ma związek z ustawieniem wartości w BuildConfig na ostateczne wartości. Może to mieć coś wspólnego z Twoim problemem.

Proste wyjaśnienie jest takie, że wartości domyślne są ustawiane początkowo przed uruchomieniem Proguard, a następnie po uruchomieniu Proguard plik BuildConfig jest ponownie generowany z odpowiednimi wartościami. Jednak Proguard już zoptymalizował Twój kod do tego momentu i masz problemy.

Oto błąd, który stworzyłem przeciwko Gradle. https://code.google.com/p/android/issues/detail?id=182449

OPOWIEŚĆ
źródło