domingo, 4 de março de 2012

Android, processamento concorrente, threads

 O objetivo principal deste post é mostrar um exemplo de processamento concorrente no Android, com compartilhamento simultâneo de dados.
 Para isso vamos usar threads, sincronização, variável volatile e interrupt. Aproveitando o teste, também usamos um ListAdapter customizado do BaseAdapter e as classes: Bundle, Message e Handler.
 Vamos inicialmente montar um projeto que consiste em utilizar um objeto para controlar um contador sequencial, uma thread para usar o contador e enviar mensagens com o último número gerado no contador para a activity, esta receberá as mensagens e mostrará os números em uma ListView.
 Vamos começar pelas telas. A tela main.xml, consiste em uma linha de status, dois botões de start e stop e a ListView que vai ser populada com o linhalista.xml que contém dois TextViews.

main.xml

 

 linhalista.xml

 

 Os dados que estamos tratando são o nome da Thread e o valor do contador. Usamos a classe Bundle para passar esses dois campos, e a classe Message para transferir o Bundle da thread para a activity via sendMessage da classe Handler. Na activity, o handler via handleMessage envia o Bundle para a lista e daí para a ListView.

 Segue o ListAdapter: MyListAdapter.java




E o contador: ContadorSequencial.java



Na thread, é importantíssimo notar que a variável workThread é definida como volatile. Ela deve ser definida dessa forma para garantir que ao ser alterada por outra thread ela seja visível para a thread com as alterações, caso contrário a thread pode não encerrar nunca!

 Segue a Thread: MyThread.java



Segue a activity: TesteThread03Activity.java



Ao executar temos a seguinte imagem:



 Vamos fazer as seguintes alterações na activity:

Acrescentar essas variáveis:

Incluir no final do onCreate:

Incluir no iniciarThreads:

Incluir no pararThreads:

E testar, e ver algo assim:

Vemos que cada thread está usando um contador separado, cada um com sua própria sequencia.

E se pretendermos que seja uma contagem única? O quê precisamos fazer?

Primeiramente, devemos alterar a classe do contador para permitir compartilhamento seguro entre Threads, colocando a palavra synchronized nos métodos que acessam a variável contador. Isso vai garantir que quando estivermos acessando a variável por uma thread, uma outra que tentar acessar vai esperar a outra liberar.
Depois alterar a activity, e passar a mesma referência do objeto contador para as três threads.

ContadorSequencial.java


O método iniciarThreads, fica assim:



E testando:



Pronto!

Abraços







Nenhum comentário:

Postar um comentário