Android é com o DemoDroid!

Comprei um celular com Android e, a esta altura, isto já não é mais novidade para ninguém. Mudei de iPhone para Android por um motivo muito simples: odeio Objective-C. Ah, e também odeio a política de publicação de aplicativos da Apple. Ah, e também acho simplesmente um assalto ter que dar 60% do valor do meu aplicativo para eles. É, acho que agora acabei minha lista negra contra o iPhone. 🙂 Mas, no mais, eu gostava dele. Só que agora, achei um concorrente: Samsung Galaxy S. Sensacional.

Mas, cala a boca, Marlon. Você não criou esse post para se vangloriar de seu novo celular e nem para falar mal da Apple. Na verdade, eu queria falar do DemoDroid. Não, não tem nenhuma relação com culto ao Satanás. DemoDroid é a junção das ideias que vivenciei no desenvolvimento do projeto Demoiselle com o ambiente do Android. E surgiram várias coisas legais dessa brincadeira. Por enquanto, vou só dar uma pincelada em umas ideias. Depois, faço mais alguns posts com mais detalhes! Agora é só para você ficar com vontade.

Vamos lá. Para quem já programou em Android, sabe que existem algumas tarefas chatas de serem feitas. Abrir e fechar conexão com o banco de dados é uma delas. Usar Cursor, então… para quem veio do mundo Java e sempre usou Hibernate, sente coceiras quando vê que no Android você precisa voltar a escrever código SQL e iterar em um Cursor para obter os dados. Então, resolvi criar um conjunto bem pequeno de classes, de forma que não tivessem impacto muito grande, para facilitar isto. E aí minha classe da camada de persistência ficou com trechos de código assim:

public class TrackingPersistence extends SQLiteCrud<Tracking> {

	@Inject
	@SQLite
	private EntityManager entityManager;

	public List<Tracking> findNotDeliveredTrackings() {
		Query query = entityManager.createQuery(Tracking.class, "select * from tracking where has_arrived = 0 and send_date IS NULL");
		return (List<Tracking>) query.getResultList();
	}
}

Bem mais clean, né não? E é isso mesmo que você está pensando: usei um pouco da ideia do JPA. Perceba ali que injeto um EntityManager e qualifico para ser injetado um que trabalhe com SQLite. Injetado? Como assim? Tem CDI no Android? É, tem sim. Na verdade, é o Google Guice. Você pode usar ele através do projeto RoboGuice. Vê lá que também tem a interface Query, igual ao JPA. A diferença é que você precisa colocar um código SQL puro e não mais HQL ou JPQL. Eu sei, isso é chato. Mas é Android, lembre. Fazer um parser de uma linguagem intermediária para SQL nativo seria muito custoso para um dispositivo. Ficou curioso para ver a entidade Tracking? Vamos lá:

@Entity
@Table(name = "tracking")
public class Tracking {

	@Id
	public long id;

	public String code;

	public Date send_date;

	public boolean has_arrived;

	public boolean taxed = false;

	@Transient
	public boolean has_changed = false;

	@Transient
	public Status lastStatus;

}

Ahhhhhhhh! Espertão! Também copiou as anotações de campos, né? Exatamente. 🙂 E funciona igualzinho a como você já sabe em JPA. Uma diferença: aqui não resolvemos relacionamentos entre entidades. Aliás, eu sequer indico que você faça relacionamentos de entidades quando estiver programando em Android. Relacionamentos são custosos demais para serem carregados e sempre bastante imprevisíveis à medida que você aumenta esta hierarquia de dependência entre os objetos. Evite!

Agora, você deve estar se perguntando: eu sei que tenho que criar as tabelas com SQL. Mas, onde você faz isso? Não faço. Ao iniciar a aplicação pela primeira vez, o próprio DemoDroid vai descobrir suas classes anotadas com @Entity e vai criar as tabelas para você. Sim, você quer saber, e que classe SQLiteCrud é essa? Ela já fornece alguns métodos CRUD por padrão para você. São os tradicionais Insert, Update, Delete, Find e FindAll. Já vem tudo implementado para você. Na sua classe de persistência você só precisa implementar os métodos a mais que precisa, como no exemplo que passei.

Vamos a outra coisa bastante usada em Android: exibição de mensagens de sucesso ou falha pra o usuário. E no Android, a forma mais trivial é usar a classe Toast. Ela é responsável em exibir aquele balão que some automaticamente depois de um tempo. Como você usaria ele normalmente? Seria assim:

	Toast toast = Toast.makeText(context, "Meu Texto", Toast.LENGTH_SHORT);
	toast.show();

Mas, certamente, você fará uma classe utilitária para evitar proliferar este mesmo código por toda a sua aplicação, certo? Pensando nisso, porque não usar algo assim?

	@Inject
	@Toaster
	private MessageContext messageContext;

	public void saveException(CodeExistsException exception) {
		messageContext.add(R.string.error_code_exists);
	}

Você poderia passar como parâmetro para o método “add” também uma String, mas o mais normal é passar o ID da string que está no seu arquivo de Resource. Feito isto, pronto. Sua mensagem vai ser exibida. Em qualquer parte da sua classe basta fazer igualzinho ao que foi feito no método saveException, pois você já injetou o contexto de mensagens. E olha uma coisa mais legal ainda: usando o MesageContext, você pode parametrizar as mensagens. Caso você crie uma mensagem no seu arquivo de resource que seja assim: “Uma Mensagem para {0}”, basta fazer messageContext.add(R.string.mensagem, “Marlon”). Entendeu? Nos próximos posts, mais pitacos sobre o DemoDroid! AH! Se eu estou usando o DemoDroid em algum projeto? Claro, no EncomendaZ para Android: https://market.android.com/details?id=net.silvacarvalho.encomendaz