Lint Tool Para Alta Performance em APPs Android

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes! Você receberá um email de confirmação. Somente depois de confirma-lo é que eu poderei lhe enviar os conteúdos semanais exclusivos. Os artigos em PDF são entregues somente para os inscritos na lista.

Email inválido.
Blog /Android /Lint Tool Para Alta Performance em APPs Android

Lint Tool Para Alta Performance em APPs Android

Vinícius Thiengo
(4622) (2)
Go-ahead
"O método consciente de tentativa e erro é mais bem-sucedido que o planejamento de um gênio isolado."
Peter Skillman
Prototipagem Android
Capa do curso Prototipagem Profissional de Aplicativos
TítuloAndroid: Prototipagem Profissional de Aplicativos
CategoriasAndroid, Design, Protótipo
AutorVinícius Thiengo
Vídeo aulas186
Tempo15 horas
ExercíciosSim
CertificadoSim
Acessar Curso
Quer aprender a programar para Android? Acesse abaixo o curso gratuito no Blog.
Lendo
TítuloManual de DevOps: como obter agilidade, confiabilidade e segurança em organizações tecnológicas
CategoriaEngenharia de Software
Autor(es)Gene Kim, Jez Humble, John Willis, Patrick Debois
EditoraAlta Books
Edição
Ano2018
Páginas464
Conteúdo Exclusivo
Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba gratuitamente conteúdos Android sem precedentes!
Email inválido

Opa, blz?

Nesse artigo vamos falar sobre a ferramenta Lint, disponível no Android Studio para identificar problemas de estrutura em nossos projetos.

Antes recapitulo que para melhorar nossos APPs, já falamos sobre Metodologias Ágeis e Código Limpo e também sobre o Proguard, esse último que, de forma quase unanime, muitos programadores Android imaginavam ser útil somente para ofuscação de código.

Com o Lint Tool estamos acrescentando mais uma ferramenta essencial para termos maior performance em nossos projetos Android.

No artigo estaremos abordando os seguintes tópicos:

O que é e qual a importância do Lint

Como já informado no início do conteúdo, o Lint é uma ferramenta que nos permite encontrar problemas em nosso projeto Android e junto a isso ele fornece algumas possíveis soluções, incluindo a possibilidade de ignorar o problema.

Há também o fornecimento da descrição e dados para identificação do problema no projeto e na página de configurações do Lint.

Na página de configurações do Lint?

Sim. No Android Studio podemos acessar e modificar as configurações que o Lint utilizará para verificar a estrutura dos arquivos do projeto.

Para acessar essa área de configurações, digo, um caminho possível para acessar essa área de configurações é indo em: File > Other Settings > Default Settings > Editor > Inspection. Você terá algo similar a pop-up abaixo:

Em breve, nesse artigo, falaremos mais sobre algumas opções dessa página de configurações.

Algo importante a saber é que as configurações que você definir para seu projeto via página de configurações do Lint, essas serão válidas também para o Code Inspector do Android Studio.

Code Inspector?

Essa é a ferramenta que válida a estrutura de seu código "on the fly", mais precisamente: valida seu código enquanto você está codificando.

Abaixo a imagem de um trecho de código Java em projeto Android onde o Code Inspector informa sobre uma inconsistência no código (template do comentário):

Ressalto que, diferente da área do Proguard na documentação do Android Studio, na área do Lint há um informe sobre o uso dessa ferramenta ser fortemente recomendado e a correção dos problemas indicados por ela também.

A correção dos problemas indicados pelo Lint na Inspector Window permite que nossos projetos fiquem com uma leitura melhor, além de melhorias no uso de memória e espaço interno no device Android.

Abaixo a figura de como funciona a execução do Lint em um projeto Android:

Você também pode utilizar o Lint pela linha de comando ou e também pode definir as configurações dele em um arquivo XML, mas isso deixo contigo, lendo a documentação Android em: Improve Your Code with Lint.

Pois não vi ganhos em utiliza-lo em linha de comando nem mesmo em trabalhar as configurações dele em arquivo XML diretamente na "unha".

Trabalhando com o Lint em um projeto de exemplo

Nesse exemplo vamos utilizar o mesmo projeto da API de anúncios da In Loco Media que está no GitHub: https://github.com/viniciusthiengo/GeoLocationAds.

Logo, baixe o projeto para poder aplicar os mesmo passos que vamos seguir aqui.

Vamos iniciar já executando o Lint. A partir desse ponto vou assumir que você está rodando o projeto indicado do GitHub acima.

Então, abra o projeto, clique com o botão direito do mouse na classe CountAds que está no package br.com.thiengo.geolocationads.domain. Logo depois clique em "Analyze" e então em "Inspect Code...":

Abrirá uma pop-up que tem algumas configurações para executar o Lint:

As opções em "Inspection scope" são referentes a escolha do escopo onde o Lint realizará a inspeção para verificar se há problemas estruturais nos arquivos desse escopo.

Em nosso caso, somente o arquivo da classe CountAds foi selecionado como escopo. Para esse primeiro passo é o suficiente.

O select ou combo box em "Inspection profile" tem as opções de profile que podem ser utilizadas para avaliação dos arquivos do escopo selecionado acima, em "Inspection scope". Essas opções do profile são as configurações de inspeção do Lint.

Quando criamos um projeto no Android Studio temos por padrão dois profiles prontos:

  • Default: contém as configurações que serão aplicadas em todos os projetos, logo, qualquer alteração nesse profile refleti no uso dele em outros projetos;
  • Project Default: contém as configurações Lint do projeto atual, qualquer alteração nesse profile refletirá somente na utilização dele no projeto atual.

Antes de clicar em "Ok" clique no botão que têm "..." como rótulo. O seguinte pop-up será apresentado a ti:

Nessa pop-up é possível atualizar todos os profiles que temos disponíveis para nosso projeto. Mas o ponto que quero abordar aqui é que somente no profile Project Default desse pop-up é que é possível realizar alterações e vê-las refletidas no projeto atual.

Por que está abordando esse detalhe?

Pois há uma outra maneira de acessarmos a página (pop-up) de configuração do Lint, digo, acessarmos os profiles e scopes. Exatamente como informado na seção O que é e qual a importância do Lint, clicando em: File > Other Settings > Default Settings > Editor > Inspections:

Nesse pop-up também há o profile Project Default, porém qualquer alteração nele vai refletir somente no Project Default de novos projetos no Android Studio a partir da data e horário dessa atualização. Já nos atuais, incluindo o projeto que está aberto, não terá efeito.

Em breve, aqui no artigo, vamos falar mais sobre algumas outras opções que apareceram nos pop-ups de configuração do Lint.

Então, caso tenha fechado a primeira janela de configuração que abrimos via classe CountAds, realize todo o procedimento novamente, deixe o escopo "Current file" selecionado e o profile "Project Default" também. Agora clique em "Ok".

Em seguida terá um resultado similar ao da imagem abaixo:

Na Inspection Window expanda todos os itens e subitens que aparecerem no quadro esquerdo. A Inspection é a janela que apresenta o resultado do Lint para que possamos corrigir o que for preciso.

Clique em "Default File Template Usage". No quadro direito da janela aparecerá algumas informações:

  • ID: identificador da inspeção que resultou no aviso para correção. Esse identificador é utilizado no gradle ou em um arquivo lint.xml para alterar a rigorosidade da inspeção ou alterar se ela está ativa ou não no profile;
  • Description: a descrição da inspeção, quais problemas ela permite o Lint identificar.

Um item abaixo de "Default File Template Usage" tem o arquivo em que foi identificado o problema, em nosso caso é a classe CountAds.

Em alguns casos esse subitem já vai nos fornecer as informações necessárias para corrigir o problema. De qualquer forma, no quadro direito aparecerá as seguintes informações:

  • Name: o local onde se encontra o problema, pode ser um recurso e até mesmo um método;
  • Location: o path do local onde se encontra o problema;
  • Problem synopsis: um resumo do problema incluindo a identificação da inspeção e a linha ou arquivo exatos para acesso ao problema;
  • Problem resolutions: essa informação nem sempre está presente, mas quando está ela contém uma ou mais opções para resolução do problema;
  • Suppress: essa parte nos dá algumas sugestões de como ignorar esse alerta de problema indicado pelo Lint. Não se engane achando que um Suppress ou Ignore sejam utilizados como são sinônimos de solução do problema, na verdade estaremos apenas indicando ao Lint que é para desconsiderar o problema marcado com Suppress ou Ignore (esse último em caso de arquivo XML).

Descendo ainda mais um nível clicamos diretamente no problema. As informações apresentadas ao lado direito na Inspection Window são com as mesmas divisões comentadas anteriormente, porém, algumas vezes, mais apuradas.

Logo, recomendo que sempre vá direto aos últimos níveis, para já acessar o local do problema e tentar alguma solução ou até mesmo um Suppress caso não seja algo relevante.

Com isso, até aqui, você já está ciente em como saber dos problemas estruturais que há em seu projeto.

Pode ser que em seu caso apareça ainda mais problemas e não somente o "Default File Template Usage" quando executando o exemplo desse artigo.

Nesse caso estude-os como fizemos com o "Default File Template Usage". Aqui vamos corrigir (atualizar) o profile para somente a inspeção comentada.

"Default File Template Usage" é a indicação de um problema referente ao template que está sendo utilizado, incluindo o template de comentários. Alias o template de comentário na classe CountAds é o problema nesse exemplo.

Em meus projetos de software eu pouco dou relevância a comentários, acredito que um código bem escrito não precisa de comentários. Os nomes de entidades bem elaborados já dizem o suficiente sobre a estrutura de código.

Logo, nosso objetivo agora será desligar a inspeção de template, até mesmo para além de comentários, pois essa inspeção não é interessante para nós em nenhum momento nesse projeto.

Vamos desliga-la somente para o profile Project Default.

Realize o processo novamente de ativação do Lint. Clique com o botão direito do mouse na classe CountAds, logo depois em "Analyze" e então em "Inspect Code...". Agora clique no botão que tem o rótulo "...".

No select de profile da pop-up que se abriu, selecione "Project Default". Em seguida, nas categorias da box de checks abaixo do select expanda "General", em seguida clique em "Default File Template Usage", como abaixo:

Note que ao lado temos um check para ativar ou desativar a inspeção. Mais ao lado temos "Description" e "Severity". Severity contém a rigorosidade atual da inspeção e para que escopo a inspeção selecionada tem a indicada severidade.

Clicando no primeiro select ao lado de Severity você pode escolher a rigorosidade da inspeção quanto ao escopo que ela for encontrada, o outro combo box.

É possível colocar rigorosidades diferentes para escopos diferentes:

Os principais escopos nesse combo box são:

  • Project Files: inclui todos os arquivos do projeto atual. Os arquivos de módulos e libraries de dependência geralmente não são incluídos;
  • Problems: inclui todos os arquivos que são internos ao projeto e que têm problemas de sintaxe;
  • Production: similar ao Project Files, porém os arquivos do diretório de arquivos de testes não são incluídos;
  • Tests: similar ao Project Files, porém somente os arquivos do diretório de arquivos de testes são incluídos;
  • Changed Files: inclui todos os arquivos que ainda não foram enviados ao versionador de código (caso um versionador esteja sendo utilizados).

Em nosso caso mantenha a rigorosidade atual, Warning, e a opção "In All Scopes" selecionada. Apenas desmarque o check ao lado de "Default File Template Usage" para que seja desativada essa inspeção.

Feito isso, clique em "Apply", depois em "Ok" e no retorno a pop-up anterior clique em "Ok" novamente.

Caso tenha tido somente a inspection trabalhada aqui como indicadora de problema, não mais aparecerá a Inspection Window para você, caso contrário somente a inspeção "Default File Template Usage" não será mais apresentada, isso utilizando o profile Project Default.

A partir daqui você já sabe como trabalhar as configurações dos profiles do Lint. Nosso próximo passo é realmente utilizar as informações fornecidas no Inspection Window para corrigir nosso projeto.

Na área de navegação dos arquivos do projeto clique em qualquer arquivo ou diretório, pode até mesmo ser na classe CountAds. Agora clique em "Analyze" e logo depois em "Inspect Code...".

Em "Inspection scope" selecione "Whole project" e logo depois, com o profile Project Default também selecionado, clique em "Ok":

Como resultado você terá algo similar a:

Você também terá algo em torno de 165 problemas estruturais encontrados.

Aqui vamos corrigir alguns poucos problemas, porém críticos, isso para você perceber a importância do uso do Lint em nossos projetos Android.

Expanda a categoria "Code maturity issues", em seguida expanda todos os subitens e então clique no último, setDrawerListener().

A estrutura apresentada ao lado já discutimos sobre anteriormente aqui no artigo, logo, vá em "Problem synopsis" e clique no número da na linha indicada como a linha do problema.

Você terá acesso ao método onCreate() da MainActivity do projeto, mais precisamente a uma linha específica desse método, indicada logo abaixo:

public class MainActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
...

@Override
protected void onCreate(Bundle savedInstanceState) {
...
drawer.setDrawerListener(toggle);
...
}
...
}

 

A inspeção que acusou essa linha foi a "Deprecated API Usage", pois setDrawerListener() está marcada para ser removida da classe DrawerLayout.

Dessa vez não houve nenhuma resolução fornecida pelo Lint. Mas a solução é simples, somente altere de setDrawerListener() para addDrawerListener(). Dessa forma esse problema já estará solucionado.

Voltando a Inspection Window expanda "Android > Lint > Performance". Logo depois expanda "Unused resources". Expanda "app" e então clique em qualquer um dos recursos indicados:

Dessa vez vamos seguramente utilizar o "Problem resolution" fornecido. Mais precisamente a primeira opção, "Remove All Unused Resources".

Essa opção removerá todos os recursos ali apresentados que segundo a ferramenta Lint não estão sendo utilizados, referenciados.

Nesse projeto eu tenho certeza que esses recursos realmente não estão sendo utilizados, mas em seu caso certifique-se de que seu código não está utilizando reflexão antes de remover qualquer recurso.

Lembrando que a opção shrinkResources que podemos definir no build, no Gradle APP Level, tem como objetivo remover recursos não utilizados, mas se pudermos adiantar o processo pelo Lint, excelente.

Observação: Se você não entendeu quando falei sobre o shrinkResources, logo depois da leitura desse artigo recomendo que leia o artigo com vídeo Proguard Android.

Clicado em "Remove All Unused Resources" mais um problema será resolvido.

Agora, para finalizar, ainda em "Android > Lint > Performance" expanda "Overdraw: Painting regions more than once" e logo em seguida expanda "app". Clique na primeira opção, terá algo como:

Os três problemas apresentados são devido ao atributo android:background que está sendo utilizado nos layouts informados.

Isso, pois o tema que está sendo referenciado nas activities em que esses layouts são carregados, esse tema já aplica um background por padrão, com isso estamos forçando o repaint do background, duas vezes para cada um dos layouts indicados no Inspection Window.

Vamos as soluções. Para que o background atual nos layouts activity_main.xml e activity_game.xml seja aplicado sem o problema de Overdraw, devemos alterar os arquivos /values/styles.xml e /v21/styles.xml.

Começando pelo /values/styles.xml:

<resources>
<style name="AppTheme" parent="Theme.AppCompat">
...
<item name="android:windowBackground">@drawable/soccer_field</item>
</style>

<style name="AppTheme.NoActionBar">
...
<item name="android:windowBackground">@drawable/soccer_field</item>
</style>
...
</resources>

 

Adicione as linhas destacadas. Foi necessário aplicar o atributo android:windowBackground em dois temas, pois a MainActivity utiliza o tema AppTheme.NoActionBar e a GameActivity utiliza o tema AppTheme.

Você consegue conferir isso no AndroidManifest.xml do projeto: 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="br.com.thiengo.geolocationads">
...

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme"
android:name=".CustomApplication">
...

<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
...
</activity>

<activity android:name=".GameActivity"/>
</application>

</manifest>

 

Note que a MainActivity tem o atributo android:theme explicito definindo o tema dela, já a GameActivity não, logo essa herda o tema definido na tag <application>.

Com isso podemos partir para a atualização do arquivo /v21/styles.xml que funciona somente para devices com o Android a partir da API 21:

<resources>
<style name="AppTheme.NoActionBar">
...
<item name="android:windowBackground">@drawable/soccer_field</item>
</style>
</resources>

 

Adicione a linha destacada. Agora acesse os layouts activity_main.xml e activity_game.xml e remova o atributo android:background da View root de ambos.

Ainda temos de corrigir o layout game.xml. Para esse problema vamos criar um novo tema, atualizando o arquivo /values/styles.xml:

<resources>
...
<style name="GameBackgroundStyle" parent="AppTheme.NoActionBar">
<item name="android:windowBackground">@color/gameBackgroundColor</item>
</style>
...
</resources>

 

O novo tema herda de AppTheme.NoActionBar, pois ele vai ser vinculado a um layout que roda dentro da MainActivity, activity que utiliza esse tema.

No arquivo /values/colors.xml adicione:

<?xml version="1.0" encoding="utf-8"?>
<resources>
...
<color name="gameBackgroundColor">#cc103b00</color>
<color name="navigatorBackgroundColor">#303030</color>
</resources>

 

Logo abaixo você entenderá o motivo da variável de cor navigatorBackgroundColor também ter sido adicionada. Agora acesse o layout game.xml, remova o atributo android:background do View root dele e adicione o atributo e valor style="@style/GameBackgroundStyle".

Agora volte ao arquivo /values/styles.xml e adicione o seguinte novo tema:

<resources>
...
<style name="NavigatorBackgroundStyle" parent="AppTheme.NoActionBar">
<item name="android:windowBackground">@color/navigatorBackgroundColor</item>
</style>
...
</resources>

 

Logo depois acesse activity_main.xml e na tag NavigationView coloque o seguinte atributo e valor, destacados:

...
<android.support.design.widget.NavigationView
style="@style/NavigatorBackgroundStyle"
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer" />
...

 

Com isso o NavigationDrawer da APP manterá a mesma cor de background, caso contrário ela utilizaria o background soccer_field definido no tema da MainActivity.

Agora novamente rode o Lint, terá um resultado sem as inspeções: "Code maturity issues" e "Android > Lint > Performance".

E a APP estará com o layout normal dela, porém agora sem Overdraw e método depreciado:

Assim finalizamos a apresentação do Lint, não deixe de visitar os links indicados na fonte desse artigo.

Vídeo com implementação passo a passo

No vídeo abaixo há todo o passo a passo da apresentação e uso do Lint no Android Studio:

Para ter acesso ao mesmo projeto que foi utilizado no exemplo, entre no GitHub a seguir: https://github.com/viniciusthiengo/GeoLocationAds.

Conclusão

Como informado na própria documentação do Android: utilize o Lint, ele vai permitir que você crie uma APP Android com maior possibilidades de manutenção / evolução além de deixá-la ainda mais eficiente depois de corrigidos todos os pontos indicados por essa ferramenta.

No artigo do Proguard falei sobre a importância de utilizá-lo para, além das técnicas de metodologia ágil, seu projeto ter ainda mais refatoração aplicada, incluindo a remoção de arquivos e códigos não utilizados.

Agora, com o Lint e essas duas outras técnicas (ou ferramentas), o projeto tende a ser ainda menos propício a problemas, como, por exemplo, vazamento de memória, além de ter um processamento com maior desempenho.

Você deve ter notado a facilidade de uso do Lint, incluindo a atualização das configurações dele. Apesar de não ter seguido mais a fundo no artigo e vídeo, você, com um tempo, estará criando seus próprios profiles e scopes, mas sempre utilizando o Lint.

Observação: caso esteja interessado também no assunto Android Annotations, o Lint é o pré-requisito desse, pois ele é uma maneira de deixar o Lint mais apurado.

Fontes

Improve Your Code with Lint

Opções de configuração Lint

Documentação IntelliJ IDEA: Code Inspection

Documentação IntelliJ IDEA: Scope

Vlw.

Investir em Você é Barra de Ouro a R$ 2,00. Cadastre-se e receba grátis conteúdos Android sem precedentes!
Email inválido

Relacionado

Checkout Transparente da Web no AndroidCheckout Transparente da Web no AndroidAndroid
Padrão de Projeto: Cláusula de GuardaPadrão de Projeto: Cláusula de GuardaAndroid
OneSignal Para Notificações em Massa no AndroidOneSignal Para Notificações em Massa no AndroidAndroid
Proguard AndroidProguard AndroidAndroid

Compartilhar

Comentários Facebook

Comentários Blog (2)

Para código / script, coloque entre [code] e [/code] para receber marcação especifica.
Forneça seu nome válido.
Forneça seu email válido.
Forneça o comentário.
Enviando, aguarde...
Geovani (1) (0)
22/02/2017
Olá Thiengo, blz?

O que é que o Lint Tool não cobre? Será que é capaz de sugerir melhorias para seguir as diretrizes do Material Design, para refatorar o código, para seguir os princípios SOLID, etc?

Abraço,
Responder
Vinícius Thiengo (0) (0)
24/02/2017
Geovani, tudo bem aqui.

Regras específicas par ajudar na validação SOLID no código, pode ser que não seja possível. Há muitas opções, se você destrinchar algumas combinações, de repente consegue algo.

Veja esse link de improve Lint direto da documentação do Android: https://developer.android.com/studio/write/lint.html

Para a validação do Material Design, ele já ajuda indicando algumas regras nos XMLs, regras de layout, a camada onde temos o MD, mas nada de específico somente de MD. Abraço.
Responder