Eu tenho uma variável no meu código dizer que é "status".
Quero exibir algum texto no aplicativo, dependendo desse valor da variável. Isso deve ser feito com um atraso de tempo específico.
É como,
Verificar valor da variável de status
Exibir algum texto
Aguarde 10 segundos
Verificar valor da variável de status
Exibir algum texto
Aguarde 15 segundos
e assim por diante. O atraso de tempo pode variar e é definido assim que o texto é exibido.
Eu tentei Thread.sleep(time delay)
e falhou. Existe uma maneira melhor de fazer isso?
android
android-thread
Kalpa Pathum Welivitigoda
fonte
fonte
Respostas:
Você deve usar
Handler
apostDelayed
função para esse fim. Ele executará seu código com atraso especificado no thread principal da interface do usuário, para que você possa atualizar os controles da interface do usuário.fonte
Para qualquer pessoa interessada, aqui está uma classe que criei usando o código do inazaruk que cria tudo o necessário (chamei-o de UIUpdater porque o uso para atualizar periodicamente a interface do usuário, mas você pode chamá-lo como quiser):
Você pode criar um objeto UIUpdater dentro da sua classe e usá-lo da seguinte maneira:
Se você quiser usar isso como um atualizador de atividades, coloque a chamada inicial dentro do método onResume () e a chamada final dentro de onPause (), para que as atualizações sejam iniciadas e paradas de acordo com a visibilidade da atividade.
fonte
UPDATE_INTERVAL = interval;
deve estar antesthis(uiUpdater);
deUIUpdater(Runnable uiUpdater, int interval)
(como o valor deUPDATE_INTERVAL
é usado e deve ser o passado como parâmetrointerval;
). Além disso, evite largura de mais de 80 caracteres no código, quando possível (quase sempre;)new Handler(Looper.getMainLooper())
. Em segundo lugar, ele não valida argumentos e engole Runnables nulos e intervalos negativos. Por fim, ele não leva em consideração o tempo gasto nauiUpdater.run()
linha, nem lida com possíveis exceções geradas por esse método. Também não é thread-safe, você deve fazerstart
estop
métodos sincronizados.error: call to this must be first statement in constructor
talvez haja uma solução fácil.Eu acho que o novo hotness é usar um ScheduledThreadPoolExecutor . Igual a:
fonte
Executors.newSingleThreadScheduledExecutor()
pode ser outra opção aqui.O temporizador funciona bem. Aqui, eu uso o Timer para pesquisar texto após 1.5s e atualizar a interface do usuário. Espero que ajude.
fonte
Existem três maneiras de fazer isso:
Use ScheduledThreadPoolExecutor
Um pouco de exagero, já que você não precisa de um pool de Threads.
Usar tarefa de timer
Estilo Android antigo
Usar manipulador e executável
Estilo Android moderno
Manipulador não vazado com atividade / contexto
Declarar uma classe Handler interna que não vaza Memória na sua classe Activity / Fragment
Declarar um executável que executará sua tarefa repetitiva na sua classe Activity / Fragment
Inicialize o objeto Handler em sua Activity / Fragment (aqui FlashActivity é minha classe de atividade)
Para repetir uma tarefa após o intervalo de tempo fixo
Para parar a repetição de tarefas
ATUALIZAÇÃO: No Kotlin:
fonte
O temporizador é outra maneira de fazer o seu trabalho, mas fique quieto se
runOnUiThread
quiser adicionar se estiver trabalhando com a interface do usuário.e xml é ...
Programe uma contagem regressiva até uma hora no futuro, com notificações regulares em intervalos ao longo do caminho. Exemplo de exibição de uma contagem regressiva de 30 segundos em um campo de texto:
Para detalhes
fonte
Tente seguir o exemplo que funciona !!!
Use [Handler] no método onCreate (), que utiliza o método postDelayed () que faz com que o Runnable seja adicionado à fila de mensagens, para ser executado após o tempo especificado decorrido ser 0 no exemplo. 1
Consulte este código:
fonte
Você pode usar um manipulador para postar código executável. Esta técnica é descrita muito bem aqui: https://guides.codepath.com/android/Repeating-Periodic-Tasks
fonte
Com base na postagem acima sobre o ScheduledThreadPoolExecutor , criei um utilitário que atendia às minhas necessidades (queria disparar um método a cada 3 segundos):
fonte
No meu caso, tive que executar um processo se uma dessas condições fosse verdadeira: se um processo anterior foi concluído ou se já haviam passado 5 segundos. Então, fiz o seguinte e funcionou muito bem:
Se process1 for lido, ele executará process2. Caso contrário, ele incrementa os tempos variáveis e faz com que o manipulador seja executado após um segundo. Ele mantém um loop até o processo1 ser lido ou o tempo ser 5. Quando o tempo é 5, isso significa que 5 segundos se passaram e, a cada segundo, a cláusula if de process1.isRead () é executada.
fonte
Usando o kotlin e sua Coroutine é bastante fácil, primeiro declare um trabalho em sua classe (melhor no seu viewModel) como este:
quando você quiser criar e iniciar, faça o seguinte:
e se você quiser terminar:
PS:
viewModelScope
está disponível apenas em modelos de exibição, você pode usar outros escopos da Coroutine, comowithContext(Dispatchers.IO)
Mais informações: Aqui
fonte
Para pessoas que usam o Kotlin, a resposta do inazaruk não funcionará, o IDE exigirá que a variável seja inicializada; portanto, em vez de usar o
postDelayed
interior doRunnable
, usaremos em um método separado.Inicialize
Runnable
assim:Inicialize seu
runDelayedHandler
método assim:Como você pode ver, essa abordagem permitirá controlar o tempo de vida da tarefa, acompanhar
keepRunning
e alterá-la durante o tempo de vida do aplicativo fará o trabalho por você.fonte