Melhorar seu código com verificações de lint

Além de garantir que seu app atenda aos requisitos funcionais compilando testes, é importante saber se o código tem problemas estruturais executando-o com lint. A ferramenta lint ajuda a encontrar códigos com estrutura ineficiente que podem afetar a confiabilidade e eficiência dos seus apps Android e dificultar a manutenção do código.

Por exemplo, arquivos de recursos XML com namespaces não utilizados desperdiçam espaço e processamento. Outros problemas estruturais, como o uso de elementos obsoletos ou chamadas de API incompatíveis com as versões visadas da API, podem causar falhas na execução do código. O lint pode ajudar você a acabar com esses problemas.

Para melhorar ainda mais o desempenho do lint, adicione anotações ao código.

Visão geral

O Android Studio oferece uma ferramenta de verificação de código denominada lint para ajudar a identificar e corrigir problemas com a qualidade estrutural do código, sem executar o app nem programar casos de teste. Cada problema detectado pela ferramenta é relatado com uma mensagem descritiva e um nível de gravidade, permitindo priorizar rapidamente quais aprimoramentos essenciais são necessários. Além disso, você pode reduzir o nível de gravidade dos problemas para ignorar aqueles que não são relevantes para o projeto, bem como aumentar esse nível para destacar problemas específicos.

A ferramenta lint verifica os arquivos de origem do projeto Android para localizar possíveis bugs e melhorias de otimização em relação a critérios de precisão, segurança, desempenho, usabilidade, acessibilidade e internacionalização. Quando você usa o Android Studio, a compilação do app sempre executa as inspeções configuradas do lint e do ambiente de desenvolvimento integrado. No entanto, é possível executar manualmente as inspeções ou executar o lint na linha de comando.

Observação: quando o código é compilado no Android Studio, outras inspeções de código do IntelliJ são executadas para otimizar a análise do código.

A figura 1 mostra como a ferramenta lint processa os arquivos de origem do aplicativo.

Figura 1. Fluxo de trabalho da verificação de código com a ferramenta lint

Arquivos de origem do aplicativo
Os arquivos de origem consistem nos arquivos que compõem o projeto Android, incluindo arquivos Java, Kotlin e XML, ícones e arquivos de configuração do ProGuard.
Arquivo lint.xml
Um arquivo de configuração usado para especificar todas as verificações do lint que você quer excluir e para personalizar os níveis de gravidade dos problemas.
Ferramenta lint
Uma ferramenta de verificação de código estático que pode ser executada no projeto Android na linha de comando ou no Android Studio (consulte Executar inspeções manualmente). A ferramenta lint verifica a existência de problemas estruturais no código que possam afetar a qualidade e o desempenho de um aplicativo Android. É altamente recomendável que você corrija todos os erros detectados pelo lint antes de publicar o aplicativo.
Resultados da verificação do lint
Os resultados do lint podem ser vistos no console ou na janela Inspection Results do Android Studio. Consulte Executar inspeções manualmente.

Executar o lint na linha de comando

Se você está usando o Android Studio ou o Gradle, use o wrapper do Gradle para invocar a tarefa lint do seu projeto inserindo um dos seguintes comandos do diretório raiz do seu projeto:

  • No Windows:
        gradlew lint
        
  • No Linux ou Mac:
        ./gradlew lint
        

O resultado será semelhante ao seguinte:

    > Task :app:lint
    Ran lint on variant release: 5 issues found
    Ran lint on variant debug: 5 issues found
    Wrote HTML report to file:<path-to-project>/app/build/reports/lint-results.html
    Wrote XML report to file:<path-to-project>/app/build/reports/lint-results.xml
    

Quando a ferramenta lint conclui a verificação, ela informa caminhos para as versões XML e HTML do relatório. Você pode navegar até o relatório em HTML e abri-lo no navegador, conforme mostrado na figura 2.

Figura 2. Exemplo de relatório do lint em HTML

Se seu projeto incluir variações de compilação e você quiser executar a tarefa lint apenas para uma determinada variação, converta a primeira letra do nome da variação em maiúscula e acrescente o prefixo lint.

    gradlew lintDebug
    

Para saber mais sobre como executar tarefas do Gradle na linha de comando, consulte Compilar seu app na linha de comando.

Executar o lint com a ferramenta autônoma

Se você não está usando o Android Studio ou o Gradle, use a ferramenta autônoma do lint depois de instalar o Android SDK Tools do SDK Manager. Depois disso, você encontrará a ferramenta lint no diretório android_sdk/tools/.

Para executar o lint em uma lista de arquivos em um diretório de projeto, use este comando:

lint [flags] <project directory>

Por exemplo, você pode emitir o comando a seguir para verificar os arquivos no diretório myproject e nos subdiretórios. O ID de problema MissingPrefix indica que o lint verifique apenas a existência de atributos XML sem o prefixo de namespace Android.

lint --check MissingPrefix myproject 

Para ver a lista completa de sinalizadores e argumentos da linha de comando compatíveis com a ferramenta, use este comando:

lint --help

O exemplo a seguir mostra a saída do console quando o comando do lint é executado em um projeto denominado Earthquake.

    $ lint Earthquake

    Scanning Earthquake: ...............................................................................................................................
    Scanning Earthquake (Phase 2): .......
    AndroidManifest.xml:23: Warning: <uses-sdk> tag appears after <application> tag [ManifestOrder]
      <uses-sdk android:minSdkVersion="7" />
      ^
    AndroidManifest.xml:23: Warning: <uses-sdk> tag should specify a target API level (the highest verified version; when running on later versions, compatibility behaviors may be enabled) with android:targetSdkVersion="?" [UsesMinSdkAttributes]
      <uses-sdk android:minSdkVersion="7" />
      ^
    res/layout/preferences.xml: Warning: The resource R.layout.preferences appears to be unused [UnusedResources]
    res: Warning: Missing density variation folders in res: drawable-xhdpi [IconMissingDensityFolder]
    0 errors, 4 warnings
    

A saída acima lista quatro alertas e nenhum erro: três alertas (ManifestOrder, UsesMinSdkAttributes e UnusedResources) no arquivo AndroidManifest.xml do projeto e um alerta (IconMissingDensityFolder) no arquivo de layout Preferences.xml.

Configurar o lint para suprimir alertas

Por padrão, quando você executa uma verificação do lint, a ferramenta procura todos os problemas compatíveis com ela. Também é possível restringir os problemas verificados pelo lint e atribuir níveis de gravidade a eles. Por exemplo, você pode suprimir a verificação do lint para problemas específicos que não são relevantes para o projeto, bem como configurar o lint para relatar problemas não críticos com um nível mais baixo de gravidade.

A verificação do lint pode ser configurada para níveis diferentes:

  • Globalmente (todo o projeto)
  • Módulo do projeto
  • Módulo de produção
  • Módulo de teste
  • Arquivos abertos
  • Hierarquia de classe
  • Escopos do sistema de controle de versões (VCS, na sigla em inglês)

Configurar o lint no Android Studio

A ferramenta incorporada lint verifica o código enquanto você usa o Android Studio. Os avisos e erros podem ser visualizados de duas formas:

  • Como texto em uma janela pop-up no Code Editor. Quando o lint encontra um problema, a ferramenta destaca o código problemático em amarelo ou, para problemas mais graves, sublinha o código em vermelho.
  • Na janela Inspection Results do lint, depois de clicar em Analyze > Inspect Code. Consulte Executar inspeções manualmente.

Configurar o arquivo do lint

Especifique as preferências de verificação do lint no arquivo lint.xml. Se você estiver criando esse arquivo manualmente, coloque-o no diretório raiz do projeto Android.

O arquivo lint.xml consiste em uma tag mãe <lint> que abrange um ou mais elementos filhos <issue>. O lint define um valor de atributo id exclusivo para cada <issue>.

    <?xml version="1.0" encoding="UTF-8"?>
        <lint>
            <!-- list of issues to configure -->
    </lint>
    

Você pode alterar o nível de gravidade ou desativar a verificação do lint para um problema definindo o atributo de gravidade na tag <issue>.

Dica: para ver uma lista completa dos problemas detectados pelo lint e os IDs correspondentes, execute o comando lint --list.

Exemplo de arquivo lint.xml

O exemplo a seguir mostra o conteúdo de um arquivo lint.xml.

    <?xml version="1.0" encoding="UTF-8"?>
    <lint>
        <!-- Disable the given check in this project -->
        <issue id="IconMissingDensityFolder" severity="ignore" />

        <!-- Ignore the ObsoleteLayoutParam issue in the specified files -->
        <issue id="ObsoleteLayoutParam">
            <ignore path="res/layout/activation.xml" />
            <ignore path="res/layout-xlarge/activation.xml" />
        </issue>

        <!-- Ignore the UselessLeaf issue in the specified file -->
        <issue id="UselessLeaf">
            <ignore path="res/layout/main.xml" />
        </issue>

        <!-- Change the severity of hardcoded strings to "error" -->
        <issue id="HardcodedText" severity="error" />
    </lint>
    

Configurar a verificação do lint para arquivos de origem Java, Kotlin e XML

É possível desativar a verificação do lint para arquivos de origem Java, Kotlin e XML.

Dica: gerencie o recurso de verificação do lint para arquivos de origem Java, Kotlin ou XML na caixa de diálogo Default Preferences. Selecione File > Other Settings > Default Settings e, no painel à esquerda da caixa de diálogo Default Preferences, selecione Editor > Inspections.

Configurar a verificação do lint em Java ou Kotlin

Para desativar a verificação do lint para uma classe ou um método específico do seu projeto Android, adicione a anotação @SuppressLint ao código.

O exemplo a seguir mostra como desativar a verificação do lint para o problema NewApi no método onCreate. A ferramenta lint continuará verificando a existência do problema NewApi em outros métodos dessa classe.

Kotlin

    @SuppressLint("NewApi")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
    

Java

    @SuppressLint("NewApi")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    

O exemplo a seguir mostra como desativar a verificação do lint para o problema ParserError na classe FeedProvider:

Kotlin

    @SuppressLint("ParserError")
    class FeedProvider : ContentProvider() {
    

Java

    @SuppressLint("ParserError")
    public class FeedProvider extends ContentProvider {
    

Para suprimir a verificação de todos os problemas do lint no arquivo, use a palavra-chave all, da seguinte forma:

Kotlin

    @SuppressLint("all")
    

Java

    @SuppressLint("all")
    

Configurar a verificação do lint em XML

Use o atributo tools:ignore para desativar a verificação do lint para seções específicas de arquivos XML. Coloque o valor de namespace a seguir no arquivo lint.xml para que a ferramenta lint reconheça o atributo:

    namespace xmlns:tools="http://schemas.android.com/tools"
    

O exemplo a seguir mostra como desativar a verificação do lint para o problema UnusedResources no elemento <LinearLayout> de um arquivo de layout XML. O atributo ignore é herdado pelos elementos filhos do elemento pai em que o atributo é declarado. Neste exemplo, a verificação do lint também está desativada para o elemento filho <TextView>.

    <LinearLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        tools:ignore="UnusedResources" >

        <TextView
            android:text="@string/auto_update_prompt" />
    </LinearLayout>
    

Para desativar mais de um problema, relacione aqueles que você quer desativar em uma string separada por vírgulas. Por exemplo:

    tools:ignore="NewApi,StringFormatInvalid"
    

Para suprimir a verificação de todos os problemas do lint no elemento XML, use a palavra-chave all, da seguinte forma:

    tools:ignore="all"
    

Configurar opções do lint com o Gradle

O plug-in do Android para o Gradle permite configurar algumas opções do lint, como quais verificações serão executadas ou ignoradas, usando o bloco lintOptions {} no arquivo build.gradle do módulo. O snippet de código a seguir mostra algumas propriedades que podem ser configuradas:

    android {
      ...
      lintOptions {
        // Turns off checks for the issue IDs you specify.
        disable 'TypographyFractions','TypographyQuotes'
        // Turns on checks for the issue IDs you specify. These checks are in
        // addition to the default lint checks.
        enable 'RtlHardcoded','RtlCompat', 'RtlEnabled'
        // To enable checks for only a subset of issue IDs and ignore all others,
        // list the issue IDs with the 'check' property instead. This property overrides
        // any issue IDs you enable or disable using the properties above.
        check 'NewApi', 'InlinedApi'
        // If set to true, turns off analysis progress reporting by lint.
        quiet true
        // if set to true (default), stops the build if errors are found.
        abortOnError false
        // if true, only report errors.
        ignoreWarnings true
      }
    }
    ...
    

Criar valores de referência de alertas

Você pode capturar um instantâneo do conjunto atual de alertas do projeto e usar essa captura como valor de referência para futuras execuções de inspeção. Assim, apenas novos problemas serão relatados. O instantâneo como valor de referência permite que você comece a usar o lint para indicar falha na compilação sem ter que voltar atrás e resolver todos os problemas existentes primeiro.

Para criar um instantâneo como valor de referência, modifique o arquivo build.gradle do projeto da seguinte maneira:

    android {
      lintOptions {
        baseline file("lint-baseline.xml")
      }
    }
    

Quando você adiciona essa linha pela primeira vez, o arquivo lint-baseline.xml é criado para estabelecer o valor de referência. A partir desse momento, as ferramentas lerão o arquivo apenas para determinar o valor de referência. Se você quiser criar um novo valor de referência, exclua manualmente o arquivo e execute o lint novamente para recriá-lo.

Em seguida, execute o lint no ambiente de desenvolvimento integrado (Analyze > Inspect Code) ou na linha de comando, conforme mostrado a seguir. A saída imprime a localização do arquivo lint-baseline.xml. O local do arquivo na sua configuração pode ser diferente daquele que é mostrado aqui.

    $ ./gradlew lintDebug

    ...

    Wrote XML report to file:///app/lint-baseline.xml
    Created baseline file /app/lint-baseline.xml
    

A execução de lint registra todos os problemas atuais no arquivo lint-baseline.xml. O conjunto de problemas atuais é chamado de valor de referência, e você poderá verificar o arquivo lint-baseline.xml no controle de versões se quiser compartilhá-lo com outras pessoas.

Personalizar o valor de referência

Se você quer adicionar alguns tipos de problemas, mas não todos, ao valor de referência, pode especificar os problemas a serem adicionados editando o build.gradle do projeto da seguinte maneira:

    android {
      lintOptions {
        check 'NewApi', 'HandlerLeak'
        baseline file("lint-baseline.xml")
       }
    }
    

Depois de criar o valor de referência, se você adicionar qualquer alerta novo ao codebase, o lint listará apenas os bugs recém-introduzidos.

Alerta de valor de referência

Quando os valores de referência estiverem em vigor, você receberá um alerta informando que um ou mais problemas foram filtrados porque já estavam listados no valor de referência. O objetivo desse alerta é ajudar você a se lembrar de que configurou um valor de referência, porque gostaria de corrigir todos os problemas em algum momento.

Esse alerta não mostra apenas o número exato de erros e alertas que foram filtrados, mas também monitora os problemas que não são mais relatados. Essas informações indicam se você realmente corrigiu os problemas. Assim você pode recriar o valor de referência para evitar que o erro volte sem ser detectado.

Observação: valores de referência são ativados quando você executa inspeções no modo de lote no ambiente de desenvolvimento integrado, mas eles são ignorados pelas verificações no editor executadas em segundo plano quando você está editando um arquivo. Isso acontece porque os valores de referência destinam-se aos casos em que um codebase tem um grande número de alertas, mas você quer corrigir os problemas localmente enquanto trabalha no código.

Executar manualmente inspeções

Execute manualmente inspeções configuradas do lint e outras inspeções do ambiente de desenvolvimento integrado selecionando Analyze > Inspect Code. Os resultados da inspeção são exibidos na janela Inspection Results.

Definir escopo e perfil da inspeção

Selecione os arquivos que você quer analisar (escopo da inspeção) e as inspeções que serão executadas (perfil de inspeção), da seguinte forma:

  1. Na visualização Android, abra o projeto e selecione ele mesmo, uma pasta ou um arquivo para analisar.
  2. Na barra de menus, selecione Analyze > Inspect Code.
  3. Na caixa de diálogo Specify Inspection Scope, revise as configurações. Especificar o escopo da inspeção

    Figura 3. Revise as configurações do escopo da inspeção

    A combinação de opções exibida na caixa de diálogo Specify Inspection Scope varia de acordo com o item selecionado, ou seja, se ele é um projeto, uma pasta ou um arquivo. É possível alterar o objeto da inspeção selecionando um dos outros botões de opção. Consulte a caixa de diálogo Specify Inspection Scope para ver uma descrição de todos os campos possíveis na caixa de diálogo Specify Inspection Scope.

    • Quando você seleciona um projeto, arquivo ou diretório, a caixa de diálogo Specify Inspection Scope exibe o caminho para o Project, File ou Directory selecionado.
    • Quando você seleciona mais de um projeto, arquivo ou diretório, a caixa de diálogo Specify Inspection Scope exibe um botão de opção marcado para Selected files.
  4. Em Inspection profile, mantenha o perfil padrão (Project Default).
  5. Clique em OK para executar a inspeção. A figura 4 mostra os resultados do lint e de outras inspeções do ambiente de desenvolvimento integrado gerados pela execução de Inspect Code:

    Figura 4. Selecione um problema para ver a resolução

  6. Na visualização em árvore no painel à esquerda, veja os resultados da inspeção ampliando e selecionado categorias de erro, tipos e problemas.

    O painel à direita exibe o relatório de inspeção para a categoria de erro, tipo ou problema selecionado e informa o nome e a localização do erro. Se for o caso, o relatório de inspeção exibirá outras informações, como um resumo do problema, para ajudar na correção.

  7. Na visualização em árvore no painel à esquerda, clique com o botão direito em uma categoria, tipo ou problema para exibir o menu de contexto.

    Dependendo do contexto, é possível realizar algumas ou todas as ações a seguir: ir para a origem, excluir e incluir itens selecionados, suprimir problemas, editar configurações, gerenciar alertas de inspeção e executar uma inspeção novamente.

Para ver descrições dos botões da barra de ferramentas à esquerda, dos itens do menu de contexto e dos campos do relatório de inspeção, consulte Janela da ferramenta de inspeção.

Usar um escopo personalizado

Você pode usar um dos escopos personalizados fornecidos no Android Studio da seguinte forma:

  1. Na caixa de diálogo Specify Inspection Scope, clique em Custom scope.
  2. Clique na lista suspensa Custom scope para exibir as opções.

    Escolher o escopo da inspeção

    Figura 5. Selecione o escopo personalizado que você quer usar

    • Project Files: todos os arquivos do projeto atual.
    • Project Production Files: somente os arquivos de produção do projeto atual.
    • Project Test Files: somente os arquivos de teste do projeto atual. Consulte Tipos e localização de testes.
    • Open Files: somente os arquivos abertos do projeto atual.
    • Module <seu-módulo>: somente os arquivos da pasta do módulo correspondente do projeto atual.
    • Current File: somente o arquivo atual do projeto atual. Exibido quando você seleciona um arquivo ou uma pasta.
    • Class Hierarchy quando você seleciona este escopo e clica em OK, uma caixa de diálogo é exibida com todas as classes do projeto atual. Use o campo Search by Name da caixa de diálogo para filtrar e selecionar as classes a serem inspecionadas. Se você não filtrar a lista de classes, a inspeção do código verificará todas as classes.
  3. Clique em OK.

Criar um escopo personalizado

Quando você quiser inspecionar uma seleção de arquivos e diretórios diferente de todos os escopos personalizados disponíveis, poderá criar um escopo personalizado.

  1. Na caixa de diálogo Specify Inspection Scope, selecione Custom scope.
  2. Clique nos três pontos após a lista suspensa Custom Scope.

    Figura 6. Caixa de diálogo "Specify Inspection Scope"

    A caixa de diálogo Scopes é exibida.

    Figura 7. Criar um escopo personalizado

  3. Clique em Add para definir um novo escopo.
  4. Na lista suspensa Add Scope, selecione Local.

    Os escopos locais e compartilhados são usados no projeto pelo recurso Inspect Code. Um escopo Shared também pode ser usado por outros recursos do projeto com um campo de escopo. Por exemplo, quando você clica em Edit Settings para alterar as configurações de Find Usages, a caixa de diálogo exibida terá um campo Scope, onde é possível selecionar um escopo compartilhado.

    Figura 8. Selecione um escopo personalizado na caixa de diálogo Find Usages

  5. Atribua um nome ao escopo e clique em OK.

    O painel à direita da caixa de diálogo Scopes é preenchido com opções que permitem definir o escopo personalizado.

  6. Na lista suspensa, selecione Project.

    Será exibida uma lista dos projetos disponíveis.

    Observação: é possível criar o escopo personalizado para projetos ou pacotes. Nos dois casos, as etapas são as mesmas.

  7. Amplie as pastas do projeto, selecione os itens que você quer adicionar ao escopo personalizado e clique em um dos botões à direita.

    Figura 9. Definir um escopo personalizado

    • Include: inclui esta pasta e os arquivos pertencentes a ela, mas não inclui nenhuma das subpastas.
    • Include Recursively: inclui esta pasta e todos os arquivos pertencentes a ela, bem como subpastas e arquivos relacionados.
    • Exclude: exclui esta pasta e os arquivos pertencentes a ela, mas não exclui nenhuma das subpastas.
    • Exclude Recursively: exclui esta pasta e todos os arquivos pertencentes a ela, bem como subpastas e arquivos relacionados.

    A figura 10 mostra que a pasta main é incluída e que a pasta java é incluída recursivamente. A cor azul indica pastas incluídas parcialmente, e a cor verde indica pastas e arquivos incluídos recursivamente.

    Figura 10. Exemplo de padrão de um escopo personalizado

    • Se você selecionar a pasta java e clicar em Exclude Recursively, o destaque em verde desaparecerá na pasta java e em todas as pastas e arquivos relacionados.
    • Se, em vez disso, você selecionar o arquivo MainActivity.java destacado em verde e clicar em "Exclude", o arquivo MainActivity.java perderá o destaque, mas todos os demais itens na pasta java continuarão destacados em verde.
  8. Clique em OK. O escopo personalizado será exibido no fim da lista suspensa.

Revisar e editar perfis de inspeção

O Android Studio é disponibilizado com vários perfis do lint e outros perfis de inspeção, atualizados por meio do Android. Você pode usar esses perfis como estão ou editar os nomes, descrições, níveis de gravidade e escopos. Também é possível ativar e desativar grupos inteiros de perfis ou perfis individuais em um grupo.

Para acessar a caixa de diálogo Inspections:

  1. Selecione Analyze > Inspect Code.
  2. Na caixa de diálogo Specify Scope em Inspection Profile, clique em More.

    A caixa de diálogo Inspections é exibida com uma lista de inspeções compatíveis e as respectivas descrições.

    Figura 11. Inspeções compatíveis e descrições relacionadas

  3. Selecione a lista suspensa Profile para alternar entre inspeções Default (Android Studio) e Project Default (o projeto ativo). Para ver mais informações, consulte a página do IntelliJ Specify Inspection Scope Dialog (link em inglês).
  4. Na caixa de diálogo Inspections no painel à esquerda, selecione uma categoria de perfil de nível superior ou amplie um grupo e selecione um perfil específico. Quando você seleciona uma categoria de perfil, pode editar todas as inspeções dela como uma única inspeção.
  5. Selecione a lista suspensa Manage que você quer copiar ou renomear ou em que quer adicionar descrições ou exportar e importar inspeções.
  6. Quando concluir, clique em OK.