Junior
Czym jest Looper w Androidzie?
sobes.tech AI
Odpowiedź od AI
Looper to klasa w Android, która służy do zarządzania przepływem (wątkiem), czyniąc go "Looping" (cyklicznym). Przygotowuje wątek do obsługi wiadomości z kolejki wiadomości (MessageQueue) do momentu jego jawnego zakończenia.
Główne komponenty Looper:
- MessageQueue: Kolejka przechowująca wiadomości (Message) i zadania (Runnable) do wykonania w wątku Looper. Jest to struktura bezpieczna dla wątków.
- Looper: Łączy wątek z MessageQueue i cyklicznie wyciąga wiadomości z kolejki do dalszej obsługi.
- Handler: Obiekt, który umieszcza wiadomości i zadania w MessageQueue Looper i obsługuje je po wyciągnięciu z kolejki. Handler jest powiązany z określonym Looperem.
Jak działa Looper:
- Przygotowanie: W wątku wywołuje się
Looper.prepare(). Tworzy to nową instancję Looper i łączy ją z bieżącym wątkiem. Tworzona jest również MessageQueue dla tego Loopera. - Rozpoczęcie pętli: Wywołuje się
Looper.loop(). Ta metoda wchodzi w nieskończoną pętlę (dopóki Looper nie zostanie zakończony). W pętli Looper stale sprawdza MessageQueue pod kątem nowych wiadomości. - Obsługa wiadomości: Znalezienie wiadomości powoduje, że Looper ją wyciąga i wysyła do Handlera, który ją dodał do kolejki. Handler wykonuje odpowiednie zadanie (np. wywołanie
handleMessage()lubrun()dla Runnable). - Zakończenie: Aby wyjść z pętli i zakończyć Looper, należy wywołać
Looper.quit()lubLooper.quitSafely().
Typowe zastosowania Looper:
- Tworzenie wątków tła, które mają wykonywać zadania asynchroniczne i odbierać wiadomości z wątku UI lub innych wątków.
- Użycie w serwisach (IntentService korzysta z wbudowanego Loopera).
- Praca z HandlerThread (specjalna klasa wątku tworząca własny Looper i MessageQueue).
Przykład tworzenia wątku z Looperem i Handlerem:
// Tworzymy i uruchamiamy wątek
HandlerThread handlerThread = new HandlerThread("MyWorkerThread");
handlerThread.start();
// Pobieramy Looper z wątku
Looper looper = handlerThread.getLooper();
// Tworzymy Handler powiązany z Looperem
Handler handler = new Handler(looper) {
@Override
public void handleMessage(Message msg) {
// Obsługa wiadomości w wątku roboczym
// msg.what zawiera identyfikator wiadomości
// msg.obj lub msg.data mogą zawierać dane
switch (msg.what) {
case 1:
// Obsługa wiadomości typu 1
break;
case 2:
// Obsługa wiadomości typu 2
break;
}
}
};
// Wysyłanie wiadomości do wątku roboczego
handler.sendEmptyMessage(1);
// Lub uruchomienie Runnable
handler.post(new Runnable() {
@Override
public void run() {
// Kod wykonywany w wątku roboczym
}
});
// Gdy wątek nie jest już potrzebny, kończymy Looper i wątek
handlerThread.quitSafely();