quinta-feira, 22 de novembro de 2012

Dica: Estudem Threads

Programação concorrente é de longe a área em que os programadores cometem mais erros.
Tenho o costume de ler códigos de terceiros. Para estudar, e aprender técnicas diferentes.
E quando se trata de concorrência, ninguém escapa imune. Desde os novatos aos mais experientes, cometem erros nessa área.
Tenho encontrado códigos inseguros, com problemas básicos de programação concorrente, até em livros!
O problema é que detectar os erros em testes é muito difícil, pois, os erros só aparecem em condições específicas, que não ocorrem a toda hora. Um erro em programação concorrente exige que várias condições ocorram ao mesmo tempo para se manifestar.
Se é difícil encontrar os erros testando, então como encontrá-los? Boa pergunta, não é?
A resposta é: Fazendo uma análise conceitual. Se o código não atende aos princípios de programação concorrente segura, então está comprometido: mais cedo ou mais tarde, vai dar problema!

Abraços!

Meus estudos

Ultimamente não tenho tido muito tempo para me dedicar aos estudos.
Os assuntos que estou interessado no momento são os que seguem:


Processamento concorrente
 No Android, usar Threads, não é uma opção. É obrigatório.
 Então continuo estudando programação concorrente em Java.

Persistência de Dados
 SqLite e ContentProvider
 Dois assuntos que estou tentando me aprofundar.
 Se alguém souber de algum material sobre acesso concorrente a DB no Android, agradeço indicações.

Abraços

terça-feira, 20 de novembro de 2012

Singleton 2

Neste post sobre Singleton testei um exemplo que não era thread-safe, ou seja, não era para ser utilizado em uma aplicação multi-thread.

Segue abaixo dois modelos para uso concorrente.








Devo lembrar aos que forem usar um Singleton, que os dados estão na memória, então são dados voláteis.
Tenho visto algumas discussões sobre "perda" de dados dos Singletons.
Isso ocorre, por exemplo, quando uma app fica em background e o Android encerrar a app em caso de necessidade.
Minha opinião sobre esse fato é que estão querendo mais do que o recurso pode oferecer! Afinal, se necessitam dos dados em qualquer situação, persistam os dados, nunca deixá-los ficar somente na memória.

Abraços



quinta-feira, 15 de novembro de 2012

Dica: Quando usar a AsyncTask?


 A classe AsyncTask foi desenvolvida com o propósito de facilitar a execução de tarefas em uma worker thread e manter atualizações na tela (antes, durante e após o processamento da worker thread).

 Mas ela tem restrições de uso?
 A resposta é: sim.

 Ela deve ser usada em situações em que o tempo de processamento de uma tarefa seja demorado o suficiente para exigir que seja executada em uma thread separada da UI thread e que não ultrapace alguns poucos segundos.

 Isso devido ao fato de que uma AsyncTask normalmente é chamada usando uma tela de "Aguarde..." e/ou com uma barra de progresso e os usuários típicos desses equipamentos não gostam de esperar...

 Se as tarefas forem muito mais demoradas que os poucos segundos suportáveis pelo usuário, use outros recursos tais como: Executor, ThreadPoolExecutor, FutureTask e, provavelmente, em um Service.

segunda-feira, 5 de novembro de 2012

Onde usar Threads, na Activity ou num Service?


No Android toda vez que você tiver uma tarefa potencialmente demorada a recomendação é que se use uma outra Thread para processá-la.
Para isso nós temos várias alternativas para escolher como fazer.
Podemos usar uma Thread diretamente, podemos usar uma AsyncTask, podemos usar um Service (com thread), etc.
Para escolher uma opção, temos que levar em conta alguns critérios técnicos*.
- O ciclo de vida da tarefa.
- A volatilidade das informações.
- A duração da tarefa

Tudo se resume entre escolher entre uma Thread na Activity ou num Service
   1. Se o ciclo de vida da tarefa for além do ciclo de vida da Activity, devemos escolher um Service (started)
      Se não, podemos escolher um Service (bounded), uma AsyncTask ou uma Thread.
   2. Se as informações tiverem sentido apenas durante o uso da Activity
      Se as informações deverão ser salvas em arquivo ou db
   3. A duração da tarefa, uma tarefa pode demorar segundos (ou menos), minutos ou horas!
      Para tarefas com duração de (poucos) segundos, podemos usar Thread ou AsyncTask diretamente na Activity, nos outros casos use um Service.

Mas cada caso é um caso! Então precisamos analisar cuidadosamente qual opção atende melhor a nossa situação específica.
Para finalizar, não devemos nos esquecer do tratamento do encerramento da nossa tarefa.
E a experiência nos diz que tudo que pode demorar, pode ser passível de cancelamento por parte do usuário ou do próprio sistema.
Mas isso é outro assunto...

* não estamos considerando aqui a quantidade de tarefas e a possibilidade de paralelização, quando um pool de threads poderia ser uma opção.

PS: Temos novas opções: usar threads em fragments: um exemplo neste post

domingo, 4 de novembro de 2012

Testando Executor no Android - 2

 Para aproveitar os aparelhos com CPUs de múltiplos núcleos, podemos usar um executor com mais de uma thread.
 Basta alterar o onStart do post anterior como abaixo.



 Um alerta: não se empolguem com o número de threads, muitas threads podem fazer o desempenho despencar!
 Outro alerta: não se esqueçam que estamos fazendo processamento concorrente, então construam classes thread-safe!


sábado, 3 de novembro de 2012

Testando Executor no Android

 Este exemplo é uma variação do post Executando tarefas sequencialmente em outra Thread
 Neste caso, eu deixo um executor em stand-by durante todo o ciclo visível de uma activity e sempre que desejo executar uma tarefa em outra thread basta enviar a tarefa para o executor.
 Cada tarefa é colocada numa fila de execução do executor, e como o executor tem apenas uma thread cada tarefa é executada sequencialmente na ordem de solicitação.
 Para processar uma tarefa neste executor basta fazer isso:
 Runnable worker = new MyTask("task" +i, 5); 
 executor.execute(worker); 
 Em MyTask, eu coloquei um handler.post(Runnable) no início e no fim com Toast´s de notificações e um ProgressBar.

 Para testar é interessante clicar no botão "Executar task" várias vezes seguidas rapidamente ou pausadamente e ver as tarefas sendo executadas.

 Vamos aos códigos:
 TesteExecutor2Activity.java

main.xml