segunda-feira, 14 de dezembro de 2015

Android Support Annotations

Olá povo,

Vou tentar atualizar o blog com mais frequência com posts menores como este. É um assunto relativamente novo, mas pouco utilizado (e conhecido) pelos desenvolvedores (inclusive eu).

Por questões de performance, é recomendado que evitemos a estrutura "enum" em aplicações Android, substituindo-as por um inteiro (int).
Mas aí sempre vem a pergunta: e como restringir os valores? Por exemplo: digamos que a classe Encomenda possui um atributo chamado status que pode receber apenas os valores "aberto", "em trânsito", "cancelado" e "entregue".

Com as anotações do Android podemos definir uma constante do tipo int para cada status e depois informar no atributo que ele só poderá receber um desses valores.

Para utilizar as anotações do Android, adicione a seguinte dependência no build.gradle.
dependencies {
 ...
 compile 'com.android.support:support-annotations:23.+'
}

Agora vejamos o código a seguir:
class Encomenda {
    public static final int STATUS_ABERTO      = 0;
    public static final int STATUS_EM_TRANSITO = 1;
    public static final int STATUS_CANCELADO   = 2;
    public static final int STATUS_ENTREGUE    = 3;
    
    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
            STATUS_ABERTO, 
            STATUS_EM_TRANSITO, 
            STATUS_CANCELADO,
            STATUS_ENTREGUE
    })
    public @interface Status {
    }

    @Status
    public int status;
}
A anotação @Retention indica onde a anotação atuará. No nosso caso, indicamos que ela é usada apenas no processo de compilação. Mas poderíamos utiliza-la em runtime. E com a anotação @IntDef estabelecemos os valores que podem ser utilizados pelo elemento que utilizar essa anotação. Por fim, anotamos o atributo "status" o @Status para restringir os valores que podem ser atribuídos a ele.
Desta forma, o código a seguir, daria erro pois 10 não é um valor de status válido:
Encomenda encomenda = new Encomenda();
encomenda.status = 10;
Com essa abordagem, você deixa de utilizar as enums e ainda deixa o seu código robusto evitando valores inválidos.

Mas isso é só o começo! A biblioteca de Android Suppport Annotations permite:
  • Validar se um parâmetro de método pode ser nulo ou não com @Nullable ou @NonNull;
  • Informar com @StringRes que um atributo do tipo int receberá o id de um texto do values/strings.xml;
  • Determinar se um método deve executar na main thread (com @UiThread ou @MainThread) ou em uma thread separada @WorkerThread;
  • Determinar que uma variável/atributo/método receberá o RGB de uma cor utilizando @ColorInt.
  • Informar que uma chamada necessita de uma permissão no AndroidManifest.xml utilizando @RequiresPermission.
E ainda tem muito mais! Mais informações vocês podem encontrar nos links abaixo:

4br4ç05,
nglauber

4 comentários:

Unknown disse...

Muito bom o conteúdo,
Fiquei com um duvida sobre as anotações para Thread,
se eu criar um método e utilizar alguma daquelas anotações,
seria o mesmo que utilizar o runOnUiThread ou uma AsyncTask?

Desculpe a ignorância e mais uma vez, parabéns pelo post.
Valeu.

Nelson Glauber disse...

Oi Ricardo,

Boa pergunta. Na verdade é apenas um aviso. Se você chamar um método com a anotação @MainThread em uma thread separada, a IDE exibirá um erro avisando que esse método deve ser chamado na Main Thread. Dá uma olhadinha no link no final do post que tem mais detalhes.

4br4ç05,
nglauber

www.areapirataria.net disse...

Glauber, tudo bem? Gostaria de te pedir uma ajuda. Recentemente fiz um cadastro no Hostgator, já que comecei a aprender a usar PHP há uns meses e a maioria do seu funcionamento. E andei entendendo um pouco o localhost do CPANEL, mas na hora de cadastrar um hotel, nao aparece no meu servidor CPANEL. Como eu faria para utilizar o exemplo da WEB SERVICE cap 10, com "http://localhost/hotel_service/webservice.php" com o meu servidor? Agradeceria muito!

-Israel Tavares

Nelson Glauber disse...

Dúvidas relacionadas ao livro, por gentileza, postar lá no grupo de discussão do livro. O endereço estás nas primeiras páginas ;)

4br4ç05,
nglauber