Segundo o Google, devo " desativar todas as chamadas para métodos de registro no código-fonte " antes de publicar meu aplicativo Android no Google Play. Trecho da seção 3 da lista de verificação da publicação :
Certifique-se de desativar o log e desativar a opção de depuração antes de criar seu aplicativo para liberação. Você pode desativar o log removendo chamadas para métodos de log em seus arquivos de origem.
Meu projeto de código aberto é grande e é difícil fazê-lo manualmente toda vez que eu for lançado. Além disso, a remoção de uma linha de log é potencialmente complicada, por exemplo:
if(condition)
Log.d(LOG_TAG, "Something");
data.load();
data.show();
Se eu comentar a linha de log, a condição se aplica à próxima linha e as chances são de que load () não seja chamado. Essas situações são raras o suficiente para que eu possa decidir que não deveria existir?
Então, existe uma maneira melhor de fazer isso no nível do código fonte? Ou talvez alguma sintaxe inteligente do ProGuard para remover com eficiência, mas com segurança, todas as linhas de log?
fonte
sed 's_^\(\s*Log\.\)_;//'`date|tr -s \ -`'\1_g'
.Respostas:
Eu encontrar uma solução muito mais fácil é esquecer todos os
if
cheques em todo o lugar e usar apenas ProGuard para retirar qualquerLog.d()
ouLog.v()
chamadas de método quando chamamos o nosso Antrelease
-alvo.Dessa forma, sempre temos as informações de depuração sendo exibidas para compilações regulares e não precisamos fazer alterações no código para compilações de versão. O ProGuard também pode fazer várias passagens pelo bytecode para remover outras instruções indesejadas, blocos vazios e pode alinhar automaticamente métodos curtos, quando apropriado.
Por exemplo, aqui está uma configuração muito básica do ProGuard para Android:
Assim, você salvaria isso em um arquivo e ligaria para o ProGuard do Ant, passando o JAR recém-compilado e o JAR da plataforma Android que você está usando.
Veja também os exemplos no manual do ProGuard.
Atualização (4,5 anos depois): Hoje em dia eu usei o Timber for Android logging.
Além de ser um pouco melhor que a
Log
implementação padrão - a tag de log é definida automaticamente e é fácil registrar seqüências de caracteres e exceções formatadas -, você também pode especificar comportamentos de log diferentes em tempo de execução.Neste exemplo, as instruções de log serão gravadas apenas no logcat nas compilações de depuração do meu aplicativo:
A madeira é configurada no meu
Application
onCreate()
método:Então, em qualquer outro lugar do meu código, eu posso registrar facilmente:
Consulte o aplicativo de exemplo Timber para obter um exemplo mais avançado, no qual todas as instruções de log são enviadas ao logcat durante o desenvolvimento e, na produção, nenhuma instrução de depuração é registrada, mas os erros são relatados silenciosamente ao Crashlytics.
fonte
Todas as boas respostas, mas quando terminei meu desenvolvimento, não quis usar declarações if em todas as chamadas de log, nem usar ferramentas externas.
Portanto, a solução que estou usando é substituir a classe android.util.Log pela minha própria classe Log:
A única coisa que eu tinha que fazer em todos os arquivos de origem era substituir a importação do android.util.Log pela minha própria classe.
fonte
Log.d("tag", someValue.toString());
isso, é muito fácil esquecer de verificar algum Valor por não ser nulo, o que significa que ele pode gerar umNullPointerException
em produção. Ele sugere uma solução segura, mas o enganará. Nós nos umprivate static boolean DEBUG
e depoisif(DEBUG)Log.d(TAG, msg);
String
. A solução completa é descrita aqui . Aparentemente, isso tem outra desvantagem: toda chamada deve ser editada (não apenas uma linha de importação).static final boolean LOG = BuildConfig.DEBUG
e não precisar modificar esse arquivo.Sugiro ter um boolean estático em algum lugar indicando se deve ou não registrar:
Então, onde você quiser fazer login no seu código, faça o seguinte:
Agora, quando você define MyDebug.LOG como false, o compilador retira todo o código dessas verificações (já que é uma final estática, ele sabe em tempo de compilação que o código não é usado.)
Para projetos maiores, você pode começar a ter booleanos em arquivos individuais para poder habilitar ou desabilitar facilmente o log, conforme necessário. Por exemplo, estas são as várias constantes de registro que temos no gerenciador de janelas:
Com o código correspondente como:
fonte
A solução Proguard de Christopher é a melhor, mas se por algum motivo você não gostar da Proguard, aqui está uma solução de baixa tecnologia:
Logs de comentários:
Descomentar logs:
Uma restrição é que suas instruções de registro não devem se estender por várias linhas.
(Execute essas linhas em um shell UNIX na raiz do seu projeto. Se estiver usando o Windows, obtenha uma camada UNIX ou use comandos equivalentes do Windows)
fonte
//
vs.;//
)Gostaria de adicionar algumas precisões sobre o uso do Proguard com o Android Studio e o gradle, pois tive muitos problemas para remover as linhas de log do binário final.
Para fazer
assumenosideeffects
trabalhos em Proguard, há um pré-requisito.No seu arquivo gradle, você deve especificar o uso do
proguard-android-optimize.txt
arquivo como padrão.Na verdade, no
proguard-android.txt
arquivo padrão , a otimização é desabilitada com os dois sinalizadores:O
proguard-android-optimize.txt
arquivo não adiciona essas linhas, então agoraassumenosideeffects
pode funcionar.Pessoalmente , uso o SLF4J , ainda mais quando desenvolvo algumas bibliotecas que são distribuídas para outras. A vantagem é que, por padrão, não há saída. E se o integrador quiser algumas saídas de log, ele poderá usar o Logback para Android e ativar os logs, para que os logs possam ser redirecionados para um arquivo ou para o LogCat.
Se eu realmente precisar remover os logs da biblioteca final, adiciono ao meu arquivo Proguard (depois de ativar o
proguard-android-optimize.txt
arquivo, é claro):fonte
proguard-android-optimize.txt
como arquivo Proguard padrão e-assumenosideeffects
em arquivo Proguard costume eram necessários! Estou usando o shinker R8 (o padrão hoje em dia) e o log padrão do Android.Eu sugiro usar a Timber da Jake Wharton
https://github.com/JakeWharton/timber
ele resolve seu problema com a ativação / desativação e adiciona automaticamente a classe de tag
somente
logs serão usados apenas na sua versão de depuração e, em seguida, use
ou
imprimir
"Sua classe / msg" sem digitar a tag
fonte
Eu usei uma classe LogUtils como no aplicativo de exemplo do Google IO. Modifiquei isso para usar uma constante DEBUG específica do aplicativo em vez de BuildConfig.DEBUG porque o BuildConfig.DEBUG não é confiável . Então, nas minhas aulas, tenho o seguinte.
fonte
Build.DEBUG
que eu costumava usar. Também desisti das várias soluções "corretas" e usei uma solução de estilo semelhante a você.Eu consideraria usar o recurso de log do roboguice em vez do android.util.Log interno
Suas instalações desabilitam automaticamente logs detalhados e de depuração para compilações de versão. Além disso, você obtém alguns recursos bacanas de graça (por exemplo, comportamento de log personalizável, dados adicionais para cada log e muito mais)
Usar o proguard pode ser um aborrecimento e eu não enfrentaria problemas para configurar e fazê-lo funcionar com seu aplicativo, a menos que você tenha uma boa razão para isso (desativar os logs não é bom)
fonte
Estou publicando esta solução que se aplica especificamente aos usuários do Android Studio. Também descobri recentemente o Timber e o importei com sucesso no meu aplicativo, fazendo o seguinte:
Coloque a versão mais recente da biblioteca em seu build.gradle:
Em Android Studios, vá para Editar -> Localizar -> Substituir no caminho ...
Digite
Log.e(TAG,
ou, no entanto, você definiu suas mensagens de log na"Text to find"
caixa de texto. Então você apenas substitui-o porTimber.e(
Clique em Localizar e substitua tudo.
Agora, o Android Studios examinará todos os seus arquivos no seu projeto e substituirá todos os registros por madeiras.
O único problema que tive com esse método é que o gradle aparece com um milhão de mensagens de erro depois, porque não consegue encontrar "Madeira" nas importações de cada um dos seus arquivos java. Basta clicar nos erros e o Android Studios importará automaticamente "Timber" para o seu java. Depois de ter feito isso para todos os seus arquivos de erros, o gradle será compilado novamente.
Você também precisa colocar este pedaço de código no seu
onCreate
método da suaApplication
classe:Isso resultará no log do aplicativo apenas quando você estiver no modo de desenvolvimento e não na produção. Você também pode ter
BuildConfig.RELEASE
para efetuar login no modo de liberação.fonte
import android\.util\.Log\;
Substituir por:import android\.util\.Log\;\nimport timber\.log\.Timber\;
Por android.util.Log fornece uma maneira de ativar / desativar o log:
Por padrão, o método isLoggable (...) retorna false, somente depois que você setprop no dispositivo gosta desta:
Isso significa que qualquer registro acima do nível de DEBUG pode ser impresso. Referência android doc:
Assim, poderíamos usar o utilitário de log personalizado:
fonte
Se você pode executar uma substituição global (uma vez) e depois preservar alguma convenção de codificação, pode seguir o padrão frequentemente usado na estrutura do Android .
Em vez de escrever
tê-lo como
Agora, o proguard pode remover o StringBuilder e todas as strings e métodos que ele usa no caminho, da versão otimizada do DEX. Use
proguard-android-optimize.txt
e você não precisa se preocupar com android.util.Log em seuproguard-rules.pro
:Com o plug-in gradle do Android Studio, é bastante confiável, portanto você não precisa de constantes extras para controlar a remoção.
BuildConfig.DEBUG
fonte
Adicione o seguinte ao seu arquivo proguard-rules.txt
fonte
Isto é o que eu costumava fazer nos meus projetos android ..
No Android Studio, podemos fazer operações semelhantes, Ctrl + Shift + F para localizar todo o projeto (Command + Shift + F nos MacOs) e Ctrl + Shift + R para substituir ((Command + Shift + R nos MacOs))
fonte
Eu tenho uma solução muito simples. Como uso o IntelliJ para desenvolvimento, os detalhes variam, mas a ideia deve se aplicar a todos os IDEs.
Eu escolho a raiz da minha árvore de origem, clique com o botão direito do mouse e selecione "substituir". Eu, então, optar por substituir todos os "Log". com "// Log". Isso remove todas as instruções de log. Para colocá-los de volta mais tarde, repito a mesma substituição, mas desta vez como substitua todos os "// Log". com "Log".
Funciona muito bem para mim. Lembre-se de definir a substituição como sensível a maiúsculas e minúsculas para evitar acidentes como "Diálogo". Para maior segurança, você também pode executar o primeiro passo com "Log". como a sequência a ser pesquisada.
Brilhante.
fonte
Como o comentário de zserge sugeriu,
sua biblioteca de logs fornece a opção simples de ativar / desativar a impressão de logs, conforme abaixo.
Além disso, ele exige apenas alteração de
import
linha e nada precisa ser alterado paraLog.d(...);
declaração.fonte
Aprimorei a solução acima, fornecendo suporte para diferentes níveis de log e alterando-os automaticamente, dependendo se o código está sendo executado em um dispositivo ativo ou no emulador.
fonte
O ProGuard fará isso por você na versão de lançamento e agora as boas notícias do android.com:
http://developer.android.com/tools/help/proguard.html
A ferramenta ProGuard reduz, otimiza e ofusca seu código removendo código não utilizado e renomeando classes, campos e métodos com nomes semanticamente obscuros. O resultado é um arquivo .apk de tamanho menor, mais difícil de fazer a engenharia reversa. Como o ProGuard dificulta a engenharia reversa de seu aplicativo, é importante usá-lo quando ele utiliza recursos sensíveis à segurança, como quando você está licenciando seus aplicativos.
O ProGuard está integrado ao sistema de compilação Android, para que você não precise invocá-lo manualmente. O ProGuard é executado apenas quando você cria seu aplicativo no modo de liberação, portanto, não é necessário lidar com o código ofuscado ao criar seu aplicativo no modo de depuração. A execução do ProGuard é totalmente opcional, mas altamente recomendada.
Este documento descreve como ativar e configurar o ProGuard, além de usar a ferramenta de retraçar para decodificar rastreamentos ofuscados da pilha
fonte
Eu gosto de usar Log.d (TAG, alguma string, geralmente uma String.format ()).
TAG é sempre o nome da classe
Transforme Log.d (TAG, -> Logd (no texto da sua classe
Dessa forma, quando você estiver pronto para criar uma versão, defina MainClass.debug como false!
fonte
Os logs podem ser removidos usando o bash no linux e sed:
Funciona para logs de várias linhas. Nesta solução, você pode ter certeza de que os logs não estão presentes no código de produção.
fonte
Sei que essa é uma pergunta antiga, mas por que você não substituiu todas as suas chamadas de log por algo como Boolean logCallWasHere = true; // --- resto do seu registro aqui
É por isso que você saberá quando deseja colocá-los de volta e eles não afetarão sua chamada if :)
fonte
Por que não fazer
? Nenhuma biblioteca adicional é necessária, nenhuma regra de programa que tende a estragar o projeto e o compilador java deixará de fora o bytecode para esta chamada quando você criar a versão build.
fonte
Log.d("tag","msg");
e também é fácil esquecer de escrever aif(BuildConfig.DEBUG)
parte.Aqui está minha solução, se você não quiser mexer com bibliotecas adicionais ou editar seu código manualmente. Criei este bloco de anotações Jupyter para revisar todos os arquivos java e comentar todas as mensagens de log. Não é perfeito, mas o trabalho foi feito para mim.
fonte
o meu caminho:
1) ative o modo de seleção de coluna (alt + shift + insert)
2) selecione em um Log.d (TAG, "texto"); a parte 'Log'.
3), em seguida, shift + ctrl + alt + j
4) clique na seta esquerda
5) faça shift + end
6) clique em excluir.
isso remove todas as chamadas de LOG de uma vez em um arquivo java.
fonte
Você pode tentar usar este método convencional simples:
Ctrl+ Shift+R
substituir
Com
fonte
Fácil com o kotlin, basta declarar algumas funções de nível superior
fonte
a maneira mais simples;
usar
DebugLog
Todos os logs são desativados pelo DebugLog quando o aplicativo é lançado.
https://github.com/MustafaFerhan/DebugLog
fonte