quinta-feira, outubro 11, 2012

Desenvolvendo para Android: Duplo toque Indesejado

Como vimos no post anterior, uma interação do operador com um elemento da tela acionará um Listener. Existem, porém, mas algumas questões a considerar. Um exemplo destas questões é o misterioso duplo toque de um botão.

Em princípio é bastante simples controlar quando um botão (ou outro elemento) pode ser acionado pelo operador: basta usar o método setEnabled. Mas às vezes isto parece não funcionar corretamente, vide os comentários nesta discussão no stackoverflow.


Não é difícil fazer um exemplo de comportamento inesperado. Basta colocar a seguinte sequência em um listener:
  • setEnabled(false) - não deixa ninguém apertar o botão, certo?
  • um processamento longo
  • setEnabled(true) - agora pode usar o botão novamente
Se você testar isto, verá que é possivel tocar no botão durante o processamento longo e que estes toques irão gerar chamadas ao listener.

O que parece ocorrer é que o setEnabled(false) só passa a valer depois que o listener acabou o tratamento. Enquanto isto os eventos vão sendo enfileirados. Na opinião de muitos, isto é um bug e está registrado como tal.

É claro que existe um erro conceitual no código do meu exemplo: você não deve colocar processamentos longos em listeners (ou outras rotinas que estão ligadas ao tratamento da UI). O correto é você fazer estes processamentos longos em background. Se você alterar o código acima para o listener fazer o setEnabled(false), disparar o processamento longo em uma outra thread e ao final dela fazer o setEnabled(true), vai funcionar corretamente.

O problema é que não é fácil prever o que pode ser demorado (potencialmente tudo é) e é bastante trabalhoso disparar em background todas as operações. Existem relatos do duplo toque ocorrer com aplicações do próprio Android, causando a duplicação de ações.

Em resumo, você precisa se precaver pelo menos nos casos em que uma demora é certa (ou bem provável) ou as consequências de um duplo toque são graves e irreversíveis. A sua aplicação provavelmente não será indestrutível, mas vai dar para você dormir despreocupado. E, no final do dia, é o melhor que a gente consegue fazer, certo?

Nenhum comentário: