Mam zmienną w kodzie, która mówi, że to „status”.
Chcę wyświetlić tekst w aplikacji w zależności od tej zmiennej. Należy tego dokonać z określonym opóźnieniem czasowym.
To jest jak,
Sprawdź wartość zmiennej statusu
Wyświetl trochę tekstu
Poczekaj 10 sekund
Sprawdź wartość zmiennej statusu
Wyświetl trochę tekstu
Poczekaj 15 sekund
i tak dalej. Opóźnienie może się różnić i jest ustawiane po wyświetleniu tekstu.
Próbowałem Thread.sleep(time delay)
i nie udało się. Jest lepszy sposób, aby to zrobić?
android
android-thread
Kalpa Pathum Welivitigoda
źródło
źródło
Odpowiedzi:
Należy użyć
Handler
„spostDelayed
funkcję do tego celu. Spowoduje to uruchomienie kodu z określonym opóźnieniem w głównym wątku interfejsu użytkownika, dzięki czemu będzie można aktualizować kontrolki interfejsu użytkownika.źródło
Wszystkim zainteresowanym, oto klasa, którą utworzyłem za pomocą kodu inazaruk, który tworzy wszystko, co potrzebne (nazwałem go UIUpdater, ponieważ używam go do okresowej aktualizacji interfejsu, ale możesz go nazwać jak tylko chcesz):
Następnie możesz utworzyć obiekt UIUpdater w swojej klasie i użyć go w następujący sposób:
Jeśli chcesz użyć tego jako aktualizatora aktywności, umieść wywołanie start w metodzie onResume (), a wywołanie stop wewnątrz onPause (), aby aktualizacje uruchamiały się i zatrzymywały zgodnie z widocznością aktywności.
źródło
UPDATE_INTERVAL = interval;
powinno być wcześniejthis(uiUpdater);
wUIUpdater(Runnable uiUpdater, int interval)
(ponieważUPDATE_INTERVAL
używana jest wartość i powinna być tą, która została przekazana jako parametrinterval;
). W miarę możliwości unikaj także szerokości ponad 80 znaków w kodzie (prawie zawsze;)new Handler(Looper.getMainLooper())
. Po drugie, nie sprawdza poprawności argumentów, więc połyka null Runnables i ujemne interwały. Wreszcie, nie uwzględnia czasu spędzonego nauiUpdater.run()
linii, ani nie obsługuje możliwych wyjątków zgłaszanych przez tę metodę. Nie jest też wątkowo bezpieczny, powinieneś tworzyćstart
istop
synchronizować metody.error: call to this must be first statement in constructor
może jest łatwa naprawa.Myślę, że nową popularnością jest użycie ScheduledThreadPoolExecutor . Tak jak:
źródło
Executors.newSingleThreadScheduledExecutor()
może być tutaj inną opcją.Timer działa dobrze. Tutaj używam Timera do wyszukiwania tekstu po 1.5s i aktualizacji interfejsu użytkownika. Mam nadzieję, że to pomaga.
źródło
Można to zrobić na 3 sposoby:
Użyj ScheduledThreadPoolExecutor
Trochę przesady, ponieważ nie potrzebujesz puli Wątków
Użyj zadania czasowego
Stary styl Androida
Użyj Handler i Runnable
Nowoczesny styl Androida
Nieszczelny program obsługi z aktywnością / kontekstem
Zadeklaruj wewnętrzną klasę Handler, która nie przecieka Pamięć w swojej klasie Activity / Fragment
Zadeklaruj wykonalność, która wykona powtarzalne zadanie w klasie Activity / Fragment
Zainicjuj obiekt modułu obsługi w swoim działaniu / fragmencie (tutaj FlashActivity to moja klasa aktywności)
Aby powtórzyć zadanie po ustalonym przedziale czasu
Aby zatrzymać powtarzanie zadania
AKTUALIZACJA: W Kotlin:
źródło
Timer to kolejny sposób na wykonanie pracy, ale pamiętaj, aby dodać,
runOnUiThread
jeśli pracujesz z interfejsem użytkownika.a xml jest ...
Zaplanuj odliczanie do czasu w przyszłości, z regularnymi powiadomieniami o interwałach po drodze. Przykład pokazujący 30-sekundowe odliczanie w polu tekstowym:
Dla szczegółów
źródło
Wypróbuj następujący przykład, działa !!!
Użyj [Handler] w metodzie onCreate (), która wykorzystuje metodę postDelayed (), która powoduje, że Runnable jest dodawany do kolejki komunikatów, uruchamiany po upływie określonego czasu, który wynosi 0 w danym przykładzie. 1
Sprawdź ten kod:
źródło
Za pomocą modułu obsługi można opublikować kod, który można uruchomić. Ta technika jest bardzo ładnie przedstawiona tutaj: https://guides.codepath.com/android/Repeating-Periodic-Tasks
źródło
W oparciu o powyższy post dotyczący ScheduledThreadPoolExecutor , stworzyłem narzędzie, które odpowiada moim potrzebom (chciałem uruchomić metodę co 3 sekundy):
źródło
W moim przypadku musiałem wykonać proces, jeśli jeden z tych warunków był spełniony: jeśli poprzedni proces został zakończony lub jeśli minęło już 5 sekund. Zrobiłem więc następujące i działałem całkiem dobrze:
Jeśli proces1 zostanie odczytany, wykonuje proces2. Jeśli nie, zwiększa zmienne czasy i powoduje, że moduł obsługi zostanie wykonany po jednej sekundzie. Utrzymuje pętlę, dopóki proces1 nie zostanie odczytany, a czas nie będzie wynosić 5. Gdy czas wynosi 5, oznacza to, że minęło 5 sekund, aw każdej sekundzie wykonywana jest klauzula if procesu1.isRead ().
źródło
Używając kotlin i jego Coroutine, jest to dość łatwe, najpierw zadeklaruj pracę w swojej klasie (lepiej w twoim modelu widzenia) w następujący sposób:
następnie, gdy chcesz go utworzyć i uruchomić, wykonaj następujące czynności:
a jeśli chcesz to zakończyć:
PS:
viewModelScope
jest dostępny tylko w modelach widoku, możesz używać innych zasięgów Coroutine, takich jakwithContext(Dispatchers.IO)
Więcej informacji: tutaj
źródło
Dla osób korzystających z Kotlina odpowiedź inazaruka nie zadziała, IDE będzie wymagało zainicjowania zmiennej, więc zamiast używać
postDelayed
wewnątrzRunnable
, użyjemy jej w osobnej metodzie.Zainicjuj swój w
Runnable
ten sposób:Zainicjuj swoją
runDelayedHandler
metodę w następujący sposób:Jak widać, takie podejście pozwoli ci kontrolować czas życia zadania, śledzić go
keepRunning
i zmieniać w trakcie życia aplikacji, wykona zadanie za Ciebie.źródło