Co to jest Android UiThread (wątek UI)

81

Czy ktoś może mi wyjaśnić, czym dokładnie jest wątek UI? Na developer.android.com jest mowa o funkcji runOnUiThread

public final void runOnUiThread (akcja do uruchomienia)

Od: Poziom interfejsu API 1 Uruchamia określoną akcję w wątku interfejsu użytkownika. Jeśli bieżący wątek jest wątkiem interfejsu użytkownika, akcja jest wykonywana natychmiast. Jeśli bieżący wątek nie jest wątkiem interfejsu użytkownika, akcja jest wysyłana do kolejki zdarzeń wątku interfejsu użytkownika.

Czy wątek interfejsu użytkownika oznacza, że ​​będzie on uruchamiany za każdym razem, gdy działanie zostanie przesunięte w tle przez jakąś czynność interfejsu użytkownika, taką jak połączenie przychodzące lub ściemnianie ekranu itp.? Jeśli nie, co dokładnie zawiera wątek interfejsu użytkownika?

Dziękuję Ci

user434885
źródło

Odpowiedzi:

144

UIThread to główny wątek wykonywania aplikacji. W tym miejscu uruchamiana jest większość kodu aplikacji. Wszystkie składniki aplikacji (działania, usługi, dostawcy treści, odbiorniki transmisji) są tworzone w tym wątku, a wszelkie wywołania systemowe do tych składników są wykonywane w tym wątku.

Na przykład, powiedzmy, że Twoja aplikacja jest pojedynczą klasą Activity. Następnie wszystkie metody cyklu życia i większość kodu obsługi zdarzeń jest uruchamiana w tym UIThread. Są to metody, takie jak onCreate, onPause, onDestroy, onClick, itd. Ponadto, jest to miejsce gdzie wszystkie aktualizacje do interfejsu użytkownika są wykonane. Wszystko, co powoduje aktualizację lub zmianę interfejsu użytkownika, MUSI wydarzyć się w wątku interfejsu użytkownika.

Aby uzyskać więcej informacji na temat procesów i wątków aplikacji, kliknij tutaj.

Gdy jawnie odradzasz nowy wątek do pracy w tle, ten kod nie jest uruchamiany w UIThread. Więc co się stanie, jeśli ten wątek w tle będzie musiał zrobić coś, co zmieni interfejs użytkownika? Do tego runOnUiThreadsłuży. Właściwie powinieneś użyć Handlera (zobacz poniższy link, aby uzyskać więcej informacji na ten temat). Zapewnia tym wątkom w tle możliwość wykonywania kodu, który może modyfikować interfejs użytkownika. Robią to, umieszczając kod modyfikujący interfejs użytkownika w obiekcie Runnable i przekazując go do metody runOnUiThread.

Aby uzyskać więcej informacji na temat tworzenia wątków roboczych i aktualizowania ich interfejsu użytkownika, kliknij tutaj

Osobiście używam tej runOnUiThreadmetody tylko w moich testach oprzyrządowania. Ponieważ kod testowy nie jest wykonywany w UIThread, musisz użyć tej metody, aby uruchomić kod, który modyfikuje interfejs użytkownika. Dlatego używam go do wstrzykiwania zdarzeń kliknięć i klawiszy do mojej aplikacji. Mogę wtedy sprawdzić stan aplikacji, aby upewnić się, że wszystko się zgadza.

Aby uzyskać więcej informacji na temat testowania i uruchamiania kodu na UIThread, kliknij tutaj

plainjimbo
źródło
3
Świetne wyjaśnienie, szczególnie link do podstaw aplikacji, to pozycja obowiązkowa dla wszystkich początkujących, takich jak ja :)
Java Student,
1
W większości przypadków nie powinieneś używać AsyncTaskzamiast zamiast runOnUiThread?
JDJ,
5
@JDJ Te dwie techniki mają różne cele: AsyncTaskwyprowadzą cię z głównego wątku, w tło; runOnUiThread()przeniesie Cię NA główny wątek, z tła. Więc to zależy od tego, co próbujesz osiągnąć.
Richard Le Mesurier
10

Jeśli wykonujesz kod blokujący (np. Żądanie HTTP) w oddzielnym wątku, rozważ użycie AsyncTask . Jego doInBackground-Method działa w osobnym wątku. AsyncTaskdostarcza metod onProgressUpdatei onPostExecutektóre są gwarantowane do pracy w wątku UI .

Jeśli potrzebujesz aktualizacji GUI postępu (np. Przez pasek postępu), zadzwoń do publishProgressśrodka doInBackground. Prowadzi to do kolejnego wywołania, onPublishProgressktóre jest również gwarantowane do uruchomienia w wątku interfejsu użytkownika .

onPostExecutejest wywoływana automatycznie po doInBackgroundpowrocie.

Martin Pabst
źródło
5

Wszystkie rysunki interfejsu użytkownika itp. Są umieszczane w osobnym wątku. Nazywa się UIThread. Jeśli chcesz wprowadzić jakąkolwiek zmianę w UI, musisz użyć, upewnij się, że dzieje się to w kontekście UIThread. Najłatwiej to zrobić, korzystając zrunOnUiThread

the100rabh
źródło
Czy możesz przygotować struktury danych widżetów (takie jak nadmuchanie układu) w wątku bez interfejsu użytkownika, a następnie narysować je później w wątku interfejsu użytkownika?
SMBiggs,
nigdy tego nie próbowałem, ale technicznie powinno to być możliwe, ponieważ inflate tworzy tylko strukturę danych. Jest to część, w której przywiązujesz się do działania itp., Kiedy musisz to zrobić w kontekście UIThread.
the100rabh