Android Studio fornece um depurador que permite fazer o seguinte e mais:
- Selecione um dispositivo para depurar seu aplicativo.
- Definir pontos de interrupção no seu Java, Kotlin e C/C++ code.
- Examinar variáveis e avaliar expressões em tempo de execução.
Esta página inclui instruções para operações básicas de depuração. Para mais documentação, veja também os documentos de depuração do IntelliJ IDEA.
- Ativar depuração
- Inicie a depuração
- Ancertar o depurador para uma aplicação em execução
- Mude o tipo de depurador
- Use o log do sistema
- Escreva mensagens de log no seu código
- Ver o log do sistema
- Work with breakpoints
- View and configure breakpoints
- Debug frames da janela
- Inspect variables
- Adicionar pontos de observação
- Veja e altere o formato de exibição do valor do recurso
Ativar depuração
Antes de começar a depuração, você precisa se preparar da seguinte forma:
- Ativar depuração no seu dispositivo:
Se você estiver usando o emulador, isto é ativado por padrão. Mas para um dispositivo conectado, você precisa habilitar a depuração nas opções do desenvolvedor do dispositivo.
- Execute uma variante de compilação depurável:
Você precisa usar uma variante de compilação que inclua
debuggable true
na configuração de compilação. Normalmente, você pode apenas selecionar a variante padrão “debug” que está incluída em todos os projetos do Android Studio (mesmo que ela não esteja visível no arquivobuild.gradle
). Mas se você definir novos tipos de compilação que devem ser depuráveis, você deve adicionar `debuggable true` ao tipo de compilação:android { buildTypes { customDebugType { debuggable true ... } }}
Esta propriedade também se aplica a módulos com código C/C++. (A propriedade
jniDebuggable
não é mais utilizada.)Se seu aplicativo depende de um módulo de biblioteca que você também deseja depurar, essa biblioteca também deve ter um bepack com
debuggable true
para que ela mantenha seus símbolos de depuração. Para garantir que as variantes depuráveis do seu projeto de aplicativo recebam a variante depurável de um módulo de biblioteca, certifique-se de publicar versões não depuráveis de sua biblioteca.
Inicie a depuração
Pode iniciar uma sessão de depuração da seguinte forma:
- Definir alguns pontos de interrupção no código da aplicação.
- Na barra de ferramentas, seleccione um dispositivo para depurar a sua aplicação a partir do menu pendente do dispositivo alvo.
Se você não tiver nenhum dispositivo configurado, então você precisa conectar um dispositivo via USB ou criar um AVD para usar o Emulador Android.
- Na barra de ferramentas, clique em Debug .
Se você vir uma caixa de diálogo perguntando se deseja “mudar de Executar para Depurar”, isso significa que seu aplicativo já está rodando no dispositivo e ele será reiniciado para iniciar a depuração. Se você preferir manter a mesma instância do aplicativo em execução, clique em Cancel Debug e em vez disso anexe o depurador a um aplicativo em execução.
Caso contrário, o Android Studio constrói um APK, assina-o com uma chave de depuração, instala-o no dispositivo selecionado e o executa. Se você adicionar código C e C++ ao seu projeto, o Android Studio também executa o depurador LLDB na janela de depuração para depurar o seu código nativo.
- Se a janela de depuração não estiver aberta, selecione View > Tool Windows > Debug (ou clique em Debug na barra da janela de ferramentas), e então clique na aba Debugger, como mostrado na figura 1.
Figure 1. A janela Depurador, mostrando a thread atual e a árvore de objetos para uma variável
Ancertar o depurador para uma aplicação em execução
Se a sua aplicação já está em execução no seu dispositivo, você pode iniciar a depuração sem reiniciar a sua aplicação como a seguir:
- Click Attach debugger to Android process .
- Na caixa de diálogo Selecionar processo, selecione o processo ao qual você deseja anexar o depurador.
Se você estiver usando um emulador ou um dispositivo raiz, você pode verificar Mostrar todos os processos para ver todos os processos.
No menu suspenso Usar configurações do depurador Android, você pode selecionar uma configuração de execução/debug existente. (Para código C e C++, isto permite-lhe reutilizar os comandos de arranque LLDB, comandos LLDB pós-attach, e directórios de símbolos numa configuração existente). Se você não tiver uma configuração de execução/depuração existente, selecione Create New. Esta seleção permite o menu suspenso Tipo de Depuração, onde você pode selecionar um tipo de depuração diferente. Por padrão, o Android Studio usa o tipo de depuração automática para selecionar a melhor opção de depuração para você, com base no fato de seu projeto incluir código Java ou C/C++.
- Clique OK.
Aparece a janela de depuração.
Nota: O depurador do Android Studio e o coletor de lixo estão vagamente integrados. A máquina virtual do Android garante que qualquer objeto que o depurador está ciente não é lixo coletado até depois que o depurador se desconecta. Isto pode resultar em uma acumulação de objetos ao longo do tempo enquanto o depurador estiver conectado. Por exemplo, se o depurador vê uma thread em execução, o objeto associado Thread
não é lixo coletado até que o depurador se desconecte, mesmo que a thread tenha terminado.
Mude o tipo de depurador
Porque diferentes ferramentas de depuração são necessárias para depurar código Java/Kotlin e código C/C++, o depurador Android Studio permite que você selecione o tipo de depurador a ser utilizado. Por padrão, o Android Studiodecide qual depurador usar baseado em quais linguagens ele detecta em seu projeto (com o tipoAuto de depurador). No entanto, você pode selecionar manualmente o depurador na configuração do depurador (clique em Run > EditConfigurations) ou na caixa de diálogo que aparece quando você clica Run > Attach debugger to Androidprocess.
Os tipos de depuração disponíveis incluem o seguinte:
Auto Selecione este tipo de depuração se você quiser que o Android Studio escolha automaticamente a melhor opção para o código que você está depurando. Por exemplo, se você tiver algum código C ou C++ no seu projeto, o Android Studio utiliza automaticamente o tipo Dual de depuração. Caso contrário, o Android Studio utiliza o tipo Java de debug. Java Selecione este tipo de depuração se você quiser depurar apenas o código escrito em Java ou Kotlin – o Java debugger ignora quaisquer pontos de interrupção ou relógios que você definir no seu código nativo. Nativo (disponível apenas com código C/C++) Seleccione este tipo de depuração se quiser utilizar apenas LLDB para depurar o seu código. Ao utilizar este tipo de depuração, a visualização da sessão de depuração Java não está disponível. Por padrão, o LLDB inspeciona apenas o seu código nativo e ignora pontos de interrupção no seu código Java. Se você também quiser depurar o seu código Java, você deve mudar para o tipo Auto ou Dual debug.
A depuração nativa só funciona em dispositivos que satisfaçam os seguintes requisitos:
-
O dispositivo suporta
run-as
.Para verificar se o dispositivo suporta
run-as
, execute o seguinte comando na shell ADB que está ligada ao seu dispositivo:run-as your-package-name pwd
Substitua
your-package-name
pelo nome do pacote da sua aplicação. Se o dispositivo suportarun-as
, o comando deve retornar sem erros. -
O dispositivo tem
ptrace
habilitado.Para verificar se
ptrace
está habilitado, execute o seguinte comando na shell ADB que está conectada ao seu dispositivo:sysctl kernel.yama.ptrace_scope
Se
ptrace
estiver habilitado, o comando irá imprimir o valor0
ou um errounknown key
. Septrace
não estiver ativado, ele imprimirá um valor diferente de0
.
Dual (disponível apenas com código C/C++) Selecione este tipo de depuração se você quiser alternar entre depuração tanto Java como código nativo. O Android Studio anexa tanto o depurador Java quanto o LLDB ao seu processo de aplicação, um para o depurador Java e outro para o LLDB, para que você possa inspecionar pontos de interrupção tanto no seu Java quanto no código nativo sem reiniciar a sua aplicação ou alterar a sua configuração de depuração.
Na figura 2, observe as duas abas à direita do título da janela de Debug. Como a aplicação tem ambos os códigos Java e C++, uma aba é para depuração do código nativo, e a outra para depuração do código Java, como indicado por -java.
Figure 2. Separador para depuração do código nativo e separador para depuração do código Java
Nota: Se estiver a depurar código nativo que é optimizado pelo compilador, pode receber a seguinte mensagem de aviso: This function was compiled with optimizations enabled. Some debugger features may not be available
. Ao usar flags de otimização, tais como -O
flags, o compilador faz alterações no seu código compilado para que ele seja executado de forma mais eficiente. Isto pode fazer com que o depurador relate informações inesperadas ou incorretas porque é difícil para o depurador mapear o código compilado otimizado de volta para o código fonte original. Por esta razão, você deve desativar as otimizações do compilador enquanto depura seu código nativo.
Use o log do sistema
O log do sistema mostra mensagens do sistema enquanto você depura sua aplicação. Estas mensagens incluem informações de aplicativos rodando no dispositivo. Se você quiser usar o log do sistema para depurar sua aplicação, certifique-se que seu código escreve mensagens de log e imprime o stacktrace para exceções enquanto sua aplicação está na fase de desenvolvimento.
Escreva mensagens de log no seu código
Para escrever mensagens de log no seu código, use a classe Log
. As mensagens de log ajudam a entender o fluxo de execução coletando a saída de depuração do sistema enquanto você interage com a sua aplicação. As mensagens de log podem dizer-lhe que parte da sua aplicação falhou. Para mais informações sobre log, veja Write and view logs.
O exemplo a seguir mostra como você pode adicionar mensagens de log para determinar se informações de estado anteriores estão disponíveis quando sua atividade inicia:
Durante o desenvolvimento, seu código também pode pegar exceções e escrever o stack trace no systemlog:
Nota: Remova as mensagens de log de depuração e as chamadas de impressão do stack trace do seu código quando você estiver pronto para publicar sua aplicação. Você poderia fazer isto definindo um DEBUG
flag e colocando as mensagens de log de debug dentro das instruções condicionais.
Ver o log do sistema
Você pode ver e filtrar a depuração e outras mensagens do sistema na janela Logcat. Por exemplo, você pode ver mensagens quando a coleta de lixo ocorre, ou mensagens que você adiciona à sua aplicação com a classe Log
.
Para usar o logcat, inicie a depuração e seleccione a aba Logcat na barra de ferramentas inferior, como mostrado na figura 3.
Figure 3. Janela Logcat com configurações de filtro
Para uma descrição do logcat e suas opções de filtragem, veja Write and view logs com Logcat.
Work with breakpoints
Android Studio suporta vários tipos de breakpoints que acionam diferentes ações de depuração. O tipo mais comum é um breakpoint de linha que pausa a execução da sua aplicação em uma linha de código especificada. Enquanto pausa, você pode examinar variáveis, avaliar expressões e então continuar a execução linha por linha para determinar as causas dos erros em tempo de execução.
Para adicionar um ponto de interrupção de linha, proceda da seguinte forma:
- Localize a linha de código onde você quer pausar a execução, então clique na calha esquerda ao longo dessa linha de código ou coloque o caret na linha e pressione Control+F8 (no Mac, Command+F8).
- Se o seu aplicativo já está em execução, você não precisa atualizá-lo para adicionar o ponto de parada – basta clicar em Attach debugger to Android proccess . Caso contrário, comece a depuração clicando em Debug .
Figure 3. Um ponto vermelho aparece ao lado da linha quando você define um breakpoint
Quando sua execução de código atinge o breakpoint, o Android Studio pausa a execução da sua aplicação. Você pode então usar as ferramentas na aba Debugger para identificar o estado do aplicativo:
-
Para examinar a árvore de objetos de uma variável, expanda-a na visão Variables. Se a vista Variáveis não estiver visível, clique em Restaurar Vista de Variáveis .
-
Para avaliar uma expressão no ponto de execução atual, clique em Avaliar Expressão .
-
Para avançar para a próxima linha no código (sem inserir um método), clique em Passo Sobre .
-
Para avançar para a primeira linha dentro de uma chamada de método, clique em Passo Dentro de .
-
Para avançar para a próxima linha fora do método atual, clique em Passo Fora .
-
Para continuar a executar o aplicativo normalmente, clique em Retomar Programa .
Se o seu projeto usa qualquer código nativo, por padrão o tipo de depuração automática anexa tanto o depurador Java quanto o LLDB ao seu aplicativo como dois processos separados, para que você possa alternar entre inspecionar Java e pontos de interrupção C/C++ sem reiniciar o seu aplicativo ou alterar as configurações.
Nota: Para o Android Studio detectar pontos de interrupção no seu código C ou C++, você precisa usar um tipo de depuração que suporte LLDB, como Automático, Nativo ou Duplo. Você pode alterar o tipo de depuração que o Android Studio usa editando sua configuração de depuração. Para saber mais sobre os diferentes tipos de depuração, leia a seção sobre como usar outros tipos de depuração.
Quando o Android Studio implanta seu aplicativo no dispositivo de destino, a janela de depuração abre com uma guia ou sessão de depuração para cada processo de depuração, como mostrado na figura 4.
Figura 4. Depuração de código nativo usando LLDB
- Android Studio muda para a aba <seu módulo> quando o depurador LLDB encontra um ponto de interrupção no seu código C/C++. Os painéis Frames, Variáveis e Relógios também estão disponíveis e funcionam exatamente como funcionariam se você estivesse depurando o código Java. Embora o painel Threads não esteja disponível na visualização da sessão LLDB, você pode acessar seus processos de aplicação usando a lista suspensa no painel Frames. Você pode aprender mais sobre esses painéis nas seções sobre como depurar quadros de janela e inspecionar variáveis.
Nota: Enquanto inspeciona um ponto de parada no seu código nativo, o sistema Android suspende a máquina virtual que executa o bytecode Java do seu aplicativo. Isso significa que você não pode interagir com o depurador Java ou recuperar qualquer informação de estado da sua sessão de depuração Java enquanto inspeciona um ponto de interrupção no seu código nativo.
- Android Studio muda para o módulo <seu módulo>-java quando o depurador Java encontra um ponto de interrupção no seu código Java.
- Após depuração com LLDB, você pode usar o terminal LLDB na visualização de sessão LLDB para passar opções de linha de comando para LLDB. Se você tem certos comandos que você gostaria que o LLDB executasse cada vez que você começar a depurar sua aplicação, pouco antes ou pouco depois do depurador anexado ao seu processo de aplicação, você pode adicionar esses comandos à sua configuração de depuração.
>
Enquanto depura o código C/C++, você também pode definir tipos especiais de pontos de interrupção, chamados watchpoints, que podem suspender o seu processo de aplicação quando a sua aplicação interage com um determinado bloco de memória. Para saber mais, leia a seção sobre como adicionar watchpoints.
View and configure breakpoints
Para visualizar todos os breakpoints e configurar configurações de breakpoints, clique em View Breakpoints no lado esquerdo da janela Debug. A janela Pontos de Quebra aparece, como mostrado na figura 5.
Figura 5. A janela Pontos de Quebra lista todos os pontos de quebra atuais e inclui configurações de comportamento para cada
A janela Pontos de quebra permite que você ative ou desative cada ponto de quebra da lista à esquerda. Se um ponto de parada estiver desabilitado, o Android Studio não faz uma pausa no seu aplicativo quando ele atingir esse ponto de parada. Selecione um ponto de parada da lista para configurar suas configurações. Você pode configurar um ponto de parada para ser desativado no início e fazer o sistema ativá-lo depois que um ponto de parada diferente for atingido. Você também pode configurar se um ponto de parada deve ser desativado após ter sido atingido. Para definir um breakpoint para qualquer exceção, selecione Exception Breakpoints na lista de breakpoints.
Debug frames da janela
Na janela Debugger, o painel Frames permite que você inspecione o frame da pilha que causou o breakpoint atual a ser atingido. Isso permite que você navegue e examine a moldura da pilha e também inspecione a lista de threads no seu aplicativo Android. Para selecionar um thread, use o seletor de threads e visualize sua moldura de pilha. Clicar nos elementos do quadro abre a fonte no editor. Você também pode personalizar a apresentação do thread e exportar o frame de pilha como discutido no guia Window Frames.
Inspect variables
Na janela Debugger, o painel Variables permite que você inspecione variáveis quando o sistema pára seu aplicativo em um ponto de parada e você seleciona um frame do painel Frames. O painel Variáveis também permite avaliar expressões ad-hoc usando métodos estáticos e/ou variáveis disponíveis dentro do quadro selecionado.
O painel Relógios fornece funcionalidade similar, exceto que as expressões adicionadas ao painel Relógios persistem entre as sessões de depuração. Você deve adicionar relógios para variáveis e campos que você acessa frequentemente ou que fornecem estado que é útil para a sessão de depuração atual. Os painéis Variáveis e Relógios aparecem como mostrado na figura 5.
Para adicionar uma variável ou expressão à lista de Relógios, siga estes passos:
- Debugging de início.
- No painel Relógios, clique em Adicionar .
- Na caixa de texto que aparece, digite o nome da variável ou expressão que você quer assistir e pressione Enter.
Para remover um item da lista Relógios, selecione o item e depois clique em Remove .
Você pode reordenar os elementos da lista Relógios selecionando um item e depois clicando em Up ou Down .
Figura 6. As Variáveis e os Painéis de Relógios na janela Depurador
Adicionar pontos de observação
Enquanto depura o código C/C++, você pode definir tipos especiais de pontos de interrupção, chamados watchpoints, que podem suspender o processo do seu aplicativo quando o seu aplicativo interage com um determinado bloco de memória. Por exemplo, se você definir dois pontos para um bloco de memória e atribuir um watchpoint a ele, usando qualquer ponteiro para acessar esse bloco de memória aciona o watchpoint.
No Android Studio, você pode criar um watchpoint durante o tempo de execução selecionando uma variável específica, mas o LLDB atribui o watchpoint apenas ao bloco de memória que o sistema aloca a essa variável, não à variável em si. Isto é diferente de adicionar uma variável ao painel Relógios, o que permite observar o valor de uma variável mas não permite suspender o processo de aplicação quando o sistema lê ou altera o seu valor na memória.
Nota: Quando seu processo de aplicação sai de uma função e o sistema desaloca suas variáveis locais da memória, você precisa reatribuir quaisquer watchpoints que você criou para essas variáveis.
Para definir um watchpoint, você precisa atender aos seguintes requisitos:
- Seu dispositivo físico ou emulador de destino usa uma CPU x86 ou x86_64. Se o seu dispositivo usa uma CPU ARM, então você deve alinhar os limites do endereço da sua variável na memória a 4 bytes para processadores de 32 bits, ou 8 bytes para processadores de 64 bits. Você pode alinhar uma variável no seu código nativo especificando
__attribute__((aligned(num_bytes)))
na desaceleração da variável, como mostrado abaixo:// For a 64-bit ARM processorint my_counter __attribute__((aligned(8)));
- Você já atribuiu três ou menos pontos de observação. O Android Studio só suporta até quatro pontos de vigilância em dispositivos alvo x86 ou x86_64. Outros dispositivos podem suportar menos pontos de vigia.
Nota: Ao depurar a sua aplicação com ABIs ARM de 32 bits, adicionar um watchpoint ou pairar sobre variáveis dentro do código para investigar os seus valores pode causar uma falha. Como alternativa, faça a depuração usando binários de 64 bits ARM, x86 ou x86_64. Este problema será corrigido em uma próxima versão do Android Studio.
Se você atender aos requisitos acima, você pode adicionar um watchpoint da seguinte forma:
- Embora sua aplicação esteja suspensa em um breakpoint, navegue até o painel Variables na visualização da sua sessão LLDB.
-
Clique com o botão direito do mouse sobre uma variável que ocupa o bloco de memória que você deseja rastrear e selecione Adicionar Ponto de Vigilância. Um diálogo para configurar seu ponto de observação aparece, como mostrado na figura 7.
Figura 7. Adicionar um ponto de vigia a uma variável na memória
- Configure o seu ponto de vigia com as seguintes opções:
- Ativado: Você pode desmarcar esta opção se você quiser dizer ao Android Studio para ignorar o ponto de vigia por enquanto. O Android Studio ainda guarda o seu ponto de vigia para que possa aceder a ele mais tarde na sua sessão de depuração.
- Suspender: Por padrão, o sistema Android suspende seu processo de aplicação quando acessa um bloco de memória que você atribui a um ponto de vigia. Você pode desmarcar essa opção se você não quiser esse comportamento – isso revela opções adicionais que você pode usar para personalizar o comportamento quando o sistema interage com seu ponto de vigia: Mensagem de registo para o console e Remover quando atingido.
- Tipo de acesso: Selecione se o seu aplicativo deve acionar o seu watchpoint quando ele tentar ler ou escrever no bloco de memória que o sistema aloca à variável. Para activar o seu watchpoint numa leitura ou numa escrita, seleccione Qualquer.
- Click Done.
Para ver todos os seus pontos de vigia e configurar as definições dos pontos de vigia, clique em View Breakpoints no lado esquerdo da janela Debug. O diálogo Pontos de parada aparece, como mostrado na figura 8.
Figura 8. A caixa de diálogo Pontos de Interrupção lista seus pontos de observação atuais e inclui configurações de comportamento para cada
Depois de adicionar seu ponto de observação, clique em Resumir Programa no lado esquerdo da janela de Depuração para retomar seu processo de aplicação. Por padrão, se o seu aplicativo tentar acessar um bloco de memória no qual você definiu um watchpoint, o sistema Android suspende o processo do seu aplicativo e um ícone de watchpoint aparece ao lado da linha de código que o seu aplicativo executou por último, como mostrado na figura 9.
Figura 9. O Android Studio indica a linha de código que seu aplicativo executa pouco antes de acionar um watchpoint
Veja e altere o formato de exibição do valor do recurso
No modo de depuração, você pode visualizar os valores dos recursos e selecionar um formato de exibição diferente para variáveis no seu código Java. Com a guia Variáveis exibida e um quadro selecionado, faça o seguinte:
- Na lista de Variáveis, clique com o botão direito do mouse em qualquer lugar em uma linha de recurso para exibir a lista suspensa.
- Na lista suspensa, selecione Ver como e selecione o formato que você deseja usar.
Os formatos disponíveis dependem do tipo de dados do recurso que você selecionou. Você pode ver qualquer uma ou mais das seguintes opções:
- Classe: Exibir a definição da classe.
- toString: Exibir o formato da string.
- Objeto: Exibir a definição de objeto (uma instância de uma classe).
- Array: Exibe em um formato de array.
- Timestamp: Exibir data e hora da seguinte forma: aaaa-mm-dd hh:mm:ss.
- Auto: O Android Studio escolhe o melhor formato baseado no tipo de dados.
- Binário: Mostra um valor binário usando zeros e uns.
- MeasureSpec: O valor passado do pai para o filho selecionado. Ver
MeasureSpec
. - Hex: Mostrar como um valor hexadecimal.
- Primitivo: Mostrar como um valor numérico usando um tipo de dado primitivo.
- Inteiro: Exibir um valor numérico do tipo
Integer
.
Você pode criar um formato personalizado (renderizador de tipos de dados), como segue: