Como interpretar o log do Android

5 Flares Twitter 0 Facebook 4 Google+ 1 LinkedIn 0 Filament.io 5 Flares ×

Se tem uma coisa que aprendi logo que comecei a programar Android é aprender a “ler” o log. Muitos programadores não entendem o log e isso ocorre por dois motivos, preguiça ou carência de inglês.

Apenda duas coisas agora:

1) Se você tem preguiça de buscar a solução e prefere perguntar sempre pra alguém num fórum ou lista antes de procurar pela solução, você tem grandes chances de ser um eterno programador junior/pleno mas dificilmente chegará a senior. Quase certo que é impossível que um dia você se torne um analista.

2) Como assim você não sabe inglês? programador que não sabe inglês é igual a motorista que não entende pra que precisa trocar as marchas do carro. E não estou falando de ter uma fala fluente e ter morado fora do país, mas sim de palavras básicas. Você sabe de cor o nome de todos os cavaleiros do zodíaco e dos mestres de cada casa? todos pockemons e suas evoluções? então porque não sabe pouco mais de 200 palavras em inglês? com cerca de 200 palavras você já tem capacidade para compreender um texto técnico da nossa área. Então deixe de ser um bundão e vá aprender inglês.

bônus: Sempre que for fazer uma busca no google, busque em inglês. Certamente você terá mais resultados e provavelmente de maior qualidade. Sempre que for olhar um filme veja legendado, isso exercita o inconsciente do seu cérebro para a compreensão do inglês, quando você precisar usar o inglês ficará surpreso como vai aprender rápido, pois o seu cérebro, internamente, já sabia aquilo. E não me venha com mimimi de não gosto de ler. Como eu disse antes, deixe de ser um bundão.

Depois dessa puxada de orelha vamos ao assunto desta postagem, leitura de logs. Primeiro dê uma olhada na página oficial do Android sobre logs. Essa página contém dicas de como gerar os logs de sua aplicação contendo uma explicação de cada tipo de log. Não vou me extender sobre cada um destes tipos, vamos nos focar nos erros, que são a maior necessidade de nós, programadores. Sobre a estrutura do log você pode ler mais neste post bem interessante do Felipe Silveira.

Mas e quando minha app da erro? Como saber onde está e qual é o erro? O log pode ser visualizado pelo LogCat, no eclipse, ou por algum aplicativo específico diretamente no dispositivo Android. Para este segundo caso recomendo o Log Watcher, ele não é muito bonito mas é muito eficiente.

Abaixo podemos ver um exemplo de log de erro:

07-05 15:38:42.711: E/Database(3332): close() was never explicitly called on database '/data/data/com.minhaApp/databases/registros' 
07-05 15:38:42.711: E/Database(3332): android.database.sqlite.DatabaseObjectNotClosedException: Application did not close the cursor or database object that was opened here
07-05 15:38:42.711: E/Database(3332): 	at android.database.sqlite.SQLiteDatabase.<init>(SQLiteDatabase.java:1810)
07-05 15:38:42.711: E/Database(3332): 	at android.database.sqlite.SQLiteDatabase.openDatabase(SQLiteDatabase.java:817)
07-05 15:38:42.711: E/Database(3332): 	at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:851)
07-05 15:38:42.711: E/Database(3332): 	at android.database.sqlite.SQLiteDatabase.openOrCreateDatabase(SQLiteDatabase.java:844)
07-05 15:38:42.711: E/Database(3332): 	at android.app.ContextImpl.openOrCreateDatabase(ContextImpl.java:540)
07-05 15:38:42.711: E/Database(3332): 	at android.content.ContextWrapper.openOrCreateDatabase(ContextWrapper.java:203)
07-05 15:38:42.711: E/Database(3332): 	at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:98)
07-05 15:38:42.711: E/Database(3332): 	at com.db.RepositorioRegistroScript.<init>(RepositorioRegistroScript.java:42)
07-05 15:38:42.711: E/Database(3332): 	at com.minhaApp.MinhaClasse.meuMetodo3(MinhaClasse.java:360)
07-05 15:38:42.711: E/Database(3332): 	at com.minhaApp.MinhaClasse.meuMetodo2(MinhaClasse.java:311)
07-05 15:38:42.711: E/Database(3332): 	at com.minhaApp.MinhaClasse.meuMetodo1(MinhaClasse.java:288)
07-05 15:38:42.711: E/Database(3332): 	at android.os.Handler.dispatchMessage(Handler.java:99)
07-05 15:38:42.711: E/Database(3332): 	at android.os.Looper.loop(Looper.java:123)
07-05 15:38:42.711: E/Database(3332): 	at android.app.ActivityThread.main(ActivityThread.java:4669)
07-05 15:38:42.711: E/Database(3332): 	at java.lang.reflect.Method.invokeNative(Native Method)
07-05 15:38:42.711: E/Database(3332): 	at java.lang.reflect.Method.invoke(Method.java:521)
07-05 15:38:42.711: E/Database(3332): 	at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:876)
07-05 15:38:42.711: E/Database(3332): 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:634)
07-05 15:38:42.711: E/Database(3332): 	at dalvik.system.NativeStart.main(Native Method)

Pra quem não está habituado parece um pouco confuso, mas vamos aos pontos mais importantes. Tenha em mente que o log é escrito de baixo para cima. Quando algo no seu código gera um erro, esse erro é passado adiante, para o método que fez a chamada. Esse é um efeito em cascata até chegar ao Android. Dito isto podemos destacar duas informações importantes do log:

1) A mensagem de erro;

2) Onde o erro ocorreu.

A mensagem é exibida na linha mais superior do trecho com o erro e neste caso é “close() was never explicitly called on database ‘/data/data/com.minhaApp/databases/registros’ “. Esta mensagem está dizendo que uma conexão com o banco não está sendo encerrada, deixando a conexão aberta sem necessidade. Geralmente este erro não trava a aplicação mas a ideia aqui é ser didático. Depois que você entender o log poderá compreender melhor coisas mais complexas.

Mas onde esse erro ocorreu? Procure no log por uma linha que contenha o nome da sua aplicação. Neste exemplo seria “com.minhaApp”. Três linhas apresentam esse nome, linhas 11, 12 e 13, e contém ainda o nome da classe e método onde o erro ocorreu. Para ser ainda mais preciso o log indica, entre parenteses, o nome do arquivo e a linha onde o erro ocorreu:

“at com.minhaApp.MinhaClasse.meuMetodo1(MinhaClasse.java:288)”

Como dito anteriormente o log é escrito de baixo para cima e um erro é encaminhado adiante. Como existem três referências da minha app no log o erro provavelmente ocorreu na referência que estiver mais acima, neste caso na linha 11. As demais apenas chamaram esta primeira e essa informação é interessante pois o erro pode estar em uma passagem de parâmetros.

Agora que você sabe ver qual o erro e onde ele está ocorrendo, não precisa mais procurar alguém pra mostrar o log sempre que ocorre um erro na sua aplicação. E sabendo qual o erro e onde ocorre pode procurar por uma solução muito mais fácil pois já tem uma ideia de onde e porque ele está ocorrendo. Obviamente alguns casos serão mais complexos do que este  abordado aqui, mas é provável que erros complexos só ocorram quando você estiver desenvolvendo apps complexas e já tenha mais conhecimento para interpretá-los.