Quando o ADT define BuildConfig.DEBUG como false?

110

Na versão mais recente do ADT (r17), foi adicionada uma constante gerada BuildConfig.DEBUGque é definida de acordo com o tipo de construção. O problema que tenho é que nunca é definido como falso, esperava que mudasse ao fazer "Ferramentas Android -> Exportar pacote de aplicativos assinados", mas não mudou para mim.

Então, como mudo o tipo de construção?

Adicionado um recurso que permite que você execute alguns códigos apenas no modo de depuração. Builds agora geram uma classe chamada BuildConfig contendo uma constante DEBUG que é automaticamente definida de acordo com seu tipo de build. Você pode verificar a constante (BuildConfig.DEBUG) em seu código para executar funções somente de depuração

smith324
fonte
2
BuildConfig.java é gerado automaticamente pelas ferramentas de construção do Android e é colocado na pasta gen. O APK assinado deve ter BuildConfig.DEBUG = false. Não deve ser um problema para você. Você não deveria ter que tocar manualmente nesse arquivo ...
IgorGanapolsky
1
Se você usar o gradle para liberar, esse sinalizador é 100% confiável. Então, quando você faz um ./gradlew assembleDebug é verdadeiro e quando faz assembleRelease é falso.
Slott

Respostas:

56

Atualmente você pode obter o comportamento correto desabilitando "Build Automatically", limpando o projeto e, em seguida, exportando via "Android Tools -> Export Signed Application Package". Quando você executa o aplicativo BuildConfig.DEBUGdeve ser falso.

smith324
fonte
quebrado também. O que tem como consequência a exibição de todas as mensagens Log.d que devem ser omitidas por este sinalizador. ps. onde arquivar o relatório de bug?
tomi
o meu é sempre falso, mesmo durante a depuração
antes de
39

Com o Eclipse , eu sempre desabilito a opção "Construir automaticamente" antes de exportar o aplicativo na versão. Depois, limpo o projeto e exporto. Caso contrário, ele começa a compilar no modo de depuração e, em seguida, o valor de BuildConfig.DEBUG pode estar errado.

Com o Android Studio , simplesmente adiciono minha própria variável personalizada no build.gradle:

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

Quando eu construo o projeto, o BuildConfig.java é gerado da seguinte maneira:

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

Então, em meu código, posso usar:

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

Recomendo limpar depois de alternar a compilação de depuração / liberação.

Arnaud SmartFun
fonte
1
Esta solução é a melhor se você usar o proguard porque ele irá gerar uma constante com um valor literal, então seu código de depuração será completamente removido do binário no modo de lançamento.
Victor Laerte
33

Não funciona corretamente:

Problema 27940 : BuildConfig.DEBUG é "verdadeiro" para o pacote de aplicativo exportado

É decepcionante que às vezes eles lançem recursos com erros.

Randy Sugianto 'Yuku'
fonte
9
Acesse o link para o problema mencionado acima e marque-o com uma estrela se quiser que isso seja corrigido.
Guy
11

Funciona, mas observe que o arquivo de código nunca muda, mesmo ao exportar o arquivo assinado. O processo de exportação altera o valor dessa variável para falso, o que pode dar a falsa impressão de que não está funcionando. Eu testei isso com declarações de registro como

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

Ao testar, minhas instruções de Log não produzem mais nenhuma saída.

pbhowmick
fonte
1
O que exatamente você fez?
pbhowmick
2
Alterei as instâncias de BuildConfig.DEBUG para com.mypackage.BuildConfig.DEBUG e, em seguida, executei novamente o aplicativo ... e ele ainda retornou verdadeiro o tempo todo. Talvez eu tenha entendido mal sua sugestão.
Chris Rae
1
O que estou dizendo é que o código NÃO mudará. No entanto, com.mypackage.BuildConfig.DEBUG será definido como False após a compilação. Tente uma instrução de log de teste como acima (escolha uma string arbitrária para registrar), faça a exportação e execute-a. Veja se adb exibe a declaração de registro. Estou disposto a apostar que o adb não relatará essa declaração de log, significando que DEUBUG foi definido como falso.
pbhowmick
1
Não tenho certeza se sei o que você quer dizer com "o código" ... no entanto, direi que fazer uma limpeza antes de exportar o APK (como sugerido na resposta aceita) tornou BuildConfig.DEBUG e com.mypackage.BuildConfig .DEBUG relata falso conforme o esperado.
Chris Rae
Você entendeu. Esse é o comportamento esperado.
pbhowmick
10

Verifique se imports, às vezes, BuildConfig é importado de qualquer classe de biblioteca acidentalmente. Por exemplo:

import io.fabric.sdk.android.BuildConfig;

Nesse caso, BuildConfig.DEBUG sempre retornará falso ;

import com.yourpackagename.BuildConfig;

Neste caso, BuildConfig.DEBUG retornará sua variante de construção real .

ps Acabei de copiar este da minha resposta aqui: BuildConfig.DEBUG sempre falso ao construir projetos de biblioteca com gradle

Gent Berani
fonte
1
Sim, para mim foi importado acidentalmente de android.support.compat. Acho que essa é outra razão para apenas definir seu próprio campo com um nome diferente.
arekolek
5

Da Preparação para Lançamento :

Desligue o registro e a depuração

Certifique-se de desativar o registro e desabilitar a opção de depuração antes de construir seu aplicativo para lançamento. Você pode desativar o registro removendo chamadas para métodos de registro em seus arquivos de origem. Você pode desativar a depuração removendo o atributo android: debuggable da tag em seu arquivo de manifesto ou definindo o atributo android: debuggable como false em seu arquivo de manifesto. Além disso, remova todos os arquivos de log ou arquivos de teste estático que foram criados em seu projeto.

Além disso, você deve remover todas as chamadas de rastreamento de depuração adicionadas ao código, como chamadas de método startMethodTracing () e stopMethodTracing ().

Mais informações no link.

Peter
fonte
1
Achei que esse processo agora acontecesse automaticamente no momento da compilação: developer.android.com/tools/sdk/tools-notes.html
IgorGanapolsky
Causa erro em tempo de compilação: «Evite codificar o modo de depuração; deixá-lo de fora permite que compilações de depuração e lançamento atribuam um automaticamente »
Nikita Bosik
5

A solução para mim:

  1. Projeto -> Construir Automaticamente
  2. Projeto -> Limpar
  3. Projeto -> Construir
  4. Aplicativo para Android Project Export

É trabalho em r20

e.shishkin
fonte
1
Isso funcionou para mim agora (usando o ADT mais recente, eu acho). Talvez a limpeza tenha resolvido, não tenho certeza.
Jonny
3

Gostaria de propor uma solução alternativa simples se você usar o proguard durante a exportação do APK.

O Proguard fornece uma maneira de remover chamadas para funções específicas no modo de liberação. Todas as chamadas para registros de depuração podem ser removidas com a seguinte configuração emproguard-project.txt .

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

E configuração de otimização em project.properties .

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

Com isso, você não precisa se preocupar com nenhuma passagem de computação de String desnecessária para o log de depuração para o qual @Jeremyfa apontou. Os cálculos são apenas removidos na versão de lançamento.

Portanto, a solução alternativa para BuildConfig.DEBUG usa o mesmo recurso do Proguard como segue.

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

E seguindo a configuração proguard-project.txt.

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

Eu preferiria usar isso em vez de desabilitar a Build Automaticallyopção, porque isso não depende da configuração IDE individual do construtor, mas é mantido como arquivo confirmado que é compartilhado entre os desenvolvedores.

neo.kim
fonte
1

Pelo que entendi, não funciona corretamente ( problema 22241 do Android )

Tive alguns problemas em um projeto (trabalhando com Eclipse), essa constante não foi definida como verdadeira ao exportar um APK assinado do meu projeto :(

Adoraria ouvir que funciona

Vincent Mimoun-Prat
fonte
1
Ele deveria ter sido corrigido no r17, marcado como tal no bug tracker.
smith324
1
Na verdade, as bibliotecas não são compiladas no modo de lançamento no ADT ao exportar (funciona no Ant). Atualizei code.google.com/p/android/issues/detail?id=27940
Xavier Ducrohet
1
@Xav obrigado por investigar, vou parar de enviar spam para você agora. Na verdade, era o projeto principal com o qual eu estava tendo problemas (não olhei para a biblioteca dependente). Se eu puder criar um caso de teste concreto, irei postá-lo no bug tracker sobre o mesmo problema.
smith324
1

uma boa maneira é criar sua própria classe:

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
fonte
12
O problema com esse método é que, quando DEBUG for falso, o java ainda computará cada String para passá-la para sua classe personalizada. O if (DEBUG) Log.d (...) é menos elegante, mas mais eficiente.
Jeremyfa
0

Eu vi um comportamento estranho que tem a ver com quando os valores em BuildConfig são definidos para seus valores finais. Isso pode ter algo a ver com o seu problema.

A explicação simples é que os valores padrão são definidos inicialmente antes da execução do Proguard e, em seguida, após a execução do Proguard, o arquivo BuildConfig é gerado novamente com os valores apropriados. No entanto, Proguard já otimizou seu código neste ponto e você tem problemas.

Aqui está um bug que criei contra o Gradle. https://code.google.com/p/android/issues/detail?id=182449

CONTO
fonte