Kiedy potrzebuję czegoś do asynchronicznego działania , na przykład długotrwałego zadania lub logiki korzystającej z sieci, lub z jakiegokolwiek powodu, uruchomienie nowego wątku i uruchomienie działa dobrze. Utworzenie Handlera i uruchomienie go również działa. Co za różnica? Kiedy powinienem używać każdego z nich? Jakie są zalety / powody używania a, Handler
a nie a Thread
?
PS. - Ze względu na to pytanie zignorujmy AsyncTask
. - Handler().postDelayed
przypadek użycia jest dla mnie jasny, ze względu na to pytanie załóżmy, że potrzebuję natychmiastowego uruchomienia zadania.
Odpowiedzi:
Jeśli cokolwiek robisz, jest „ciężkie”, powinieneś to robić w wątku. Jeśli nie uruchomisz go jawnie we własnym wątku, będzie on działał w wątku głównym (UI), który może być zauważalny jako roztrzęsiony lub wolno reagujący interfejs użytkowników.
Co ciekawe, gdy używasz wątku, często przydatne jest również użycie Handlera jako środka komunikacji między wątkiem roboczym, który rozpoczynasz, a wątkiem głównym.
Typowa interakcja wątek / obsługa może wyglądać mniej więcej tak:
Handler h = new Handler(){ @Override public void handleMessage(Message msg){ if(msg.what == 0){ updateUI(); }else{ showErrorDialog(); } } }; Thread t = new Thread() { @Override public void run(){ doSomeWork(); if(succeed){ //we can't update the UI from here so we'll signal our handler and it will do it for us. h.sendEmptyMessage(0); }else{ h.sendEmptyMessage(1); } } };
Ogólnie rzecz biorąc, najważniejsze jest to, że powinieneś używać wątku za każdym razem, gdy wykonujesz jakąś pracę, która może być długotrwała lub bardzo intensywna (np. Wszystko w sieci, we / wy pliku, ciężka arytmetyka itp.)
źródło
updateUI()
będzie działać poonCreateView
(po załadowaniu nowych widoków)?message.what()
? Czy nie byłoby po prostuif(msg == 0){
? Dzięki wielkie! :)Handler i Thread to tak naprawdę dwie różne rzeczy.
Aby wykonywać długotrwałe zadania, należy utworzyć wątek.
Handler jest bardzo wygodnym obiektem do komunikacji między 2 wątkami (na przykład: wątek działający w tle wymaga aktualizacji interfejsu użytkownika. Możesz użyć Handlera, aby opublikować część Runnable z wątku w tle do wątku interfejsu użytkownika).
Więc nie masz wyboru między obsługą a wątkiem. Użyj nici do ciężkich prac! (możesz użyć Handlera, jeśli twój wątek w tle wyzwoli pewne zadanie do wykonania w innym wątku - w większości przypadków wątek interfejsu użytkownika)
źródło
Handler
iThread
to dwie różne rzeczy, ale nie są one sprzeczne. Możesz mieć aHandler
iThread
w tym samym czasie i właściwie każdy z nichHandler
musi być uruchomiony wThread
.Aby uzyskać więcej informacji, zapoznaj się z tym artykułem .
źródło
A
Handler
działa na tym samymThread
, aThread
działa na innym wątku.Użyj Handlera, jeśli chcesz uruchomić coś w tym samym wątku , zwykle element GUI lub coś podobnego.
Użyj wątku, jeśli chcesz, aby główny wątek mógł robić inne rzeczy . Użyj tego do wszystkiego, co zajmuje dużo czasu.
źródło
Programy obsługi to najlepszy sposób komunikacji między tłem a wątkiem interfejsu użytkownika. Zwykle programy obsługi są powiązane z kolejką wiadomości wątku i służą do wysyłania wiadomości i mogą być uruchamiane w wiadomości.
POSŁUGIWAĆ SIĘ:
Wątek: Aby wykonać zadania w wątku saperate (w tle) niż wątek interfejsu użytkownika. (pomaga odblokować wątek UI)
Handler Służy do komunikacji między interfejsem użytkownika a wątkiem w tle.
Spójrz na ten artykuł
źródło
... więcej szczegółów tutaj o nici itp (zawiera turorials dla różnych mechanizmów gwintowania i synchronizację i kiedy używać co)
źródło
Handler pozwala na wysyłanie i przetwarzania wiadomości i
Runnable
przedmioty związane z wątkuMessageQueue
. KażdaHandler
instancja jest powiązana z pojedynczym wątkiem i kolejką komunikatów tego wątku.Kiedy tworzysz nowy
Handler
, jest on powiązany z wątkiem / kolejką komunikatów wątku, który go tworzy - od tego momentu będzie dostarczał komunikaty i pliki do uruchomienia do tej kolejki komunikatów i wykonywał je, gdy wychodzą z kolejki komunikatów .Procedura obsługi ma dwa główne zastosowania:
Jeśli używasz wątków Java, musisz sobie z czymś poradzić samodzielnie - synchronizacją z wątkiem głównym, anulowaniem wątku itp.
Ten pojedynczy wątek nie tworzy puli wątków, chyba że używasz interfejsu API
ThreadPoolExecutor
lubExecutorService
.(Zaczerpnięto to zapytanie z twoich komentarzy do odpowiedzi Blackbelt)
Źródła: artykuł dotyczący wydajności wątków
Istnieją pewne rodzaje pracy, które można zredukować do wysoce równoległych, rozproszonych zadań. Przy ogromnej ilości pakietów roboczych tworzy to
AsyncTask
iHandlerThread
nie jest to odpowiednie klasy.AsyncTask
Jednowątkowy charakter zmieniłby całą pracę w puli wątków w system liniowy.HandlerThread
Z drugiej strony korzystanie z klasy wymagałoby od programisty ręcznego zarządzania równoważeniem obciążenia między grupą wątków.ThreadPoolExecutor to klasa pomocnicza ułatwiająca ten proces. Ta klasa zarządza tworzeniem grupy wątków, ustala ich priorytety i zarządza sposobem podziału pracy między te wątki. Wraz ze wzrostem lub spadkiem obciążenia klasa obraca się lub niszczy więcej wątków, aby dostosować się do obciążenia.
BlockingQueue workQueue= new LinkedBlockingQueue<Runnable>(100); // Work pool size ThreadPoolExecutor executor = new ThreadPoolExecutor( Runtime.getRuntime().availableProcessors(), // Initial pool size Runtime.getRuntime().availableProcessors(), // Max pool size 1, // KEEP_ALIVE_TIME TimeUnit.SECONDS, // KEEP_ALIVE_TIME_UNIT workQueue);
Więcej informacji można znaleźć w tym artykule przewodnika dla programistów na temat tworzenia puli wątków .
Spójrz na ten post, aby zapoznać się z używaniem programu
Handler
do uruchamiania wielu instancji Runnable. W takim przypadku wszystkieRunnable
zadania będą uruchamiane w jednym wątku.Android: Toast w wątku
źródło
Handler
może być używany w połączeniu zThread
w celu utworzenia mechanizmu kolejkowania. Możesz użyć,handler
aby opublikować coś naThread
Looper
źródło
Jeśli musisz wykonać zadanie tylko raz oddzielnie poza głównym wątkiem, użyj Thread. Jeśli chcesz wielokrotnie wykonywać zadania, system Android zapewnia sposób na utrzymanie wątków przy życiu i odbieranie wiadomości lub obiektów Runnable do przetwarzania ich za pomocą Looper w MessageQueue.
źródło