Sobes.tech
Junior

Co je to Looper v Androidu?

sobes.tech AI

Odpověď od AI

Looper je třída v Androidu, která slouží k řízení vlákna (Thread) tím, že jej činí "Looping" (cyklickým). Připravuje vlákno na zpracování zpráv z fronty zpráv (MessageQueue), dokud není výslovně ukončeno.

Hlavní komponenty Looper:

  • MessageQueue: Fronta, která uchovává zprávy (Message) a úkoly (Runnable) k provedení ve vlákně Looper. Je to vlákna bezpečná struktura.
  • Looper: Spojuje vlákno s MessageQueue a cyklicky vybírá zprávy z fronty k jejich dalšímu zpracování.
  • Handler: Objekt, který umisťuje zprávy a úkoly do MessageQueue Looperu a zpracovává je při jejich vybrání z fronty. Handler je přiřazen ke konkrétnímu Looperu.

Jak Looper funguje:

  1. Příprava: V vlákně je volána metoda Looper.prepare(). Vytvoří se nová instance Looperu a spojí se s aktuálním vláknem. Také se vytvoří MessageQueue pro tento Looper.
  2. Spuštění cyklu: Volá se Looper.loop(). Tato metoda vstupuje do nekonečného cyklu (dokud není Looper ukončen). V cyklu Looper neustále kontroluje MessageQueue na nové zprávy.
  3. Zpracování zpráv: Po nalezení zprávy ji Looper vytáhne a odešle Handleru, který ji přidal do fronty. Handler provádí odpovídající úkol (například volá metodu handleMessage() nebo run() pro Runnable).
  4. Ukončení: Pro ukončení cyklu a ukončení Looperu je třeba zavolat Looper.quit() nebo Looper.quitSafely().

Typické použití Looperu:

  • Vytváření pozadíových vláken, která mají asynchronně vykonávat úkoly a přijímat zprávy z UI vlákna nebo z jiných vláken.
  • Použití v službách (IntentService používá vestavěný Looper).
  • Práce s HandlerThread (speciální třída vlákna, která vytváří svůj Looper a MessageQueue).

Příklad vytvoření vlákna s Looperem a Handlerem:

// Vytvoření vlákna a jeho spuštění
HandlerThread handlerThread = new HandlerThread("MyWorkerThread");
handlerThread.start();

// Získání Looperu z vlákna
Looper looper = handlerThread.getLooper();

// Vytvoření Handleru přiřazeného k Looperu
Handler handler = new Handler(looper) {
    @Override
    public void handleMessage(Message msg) {
        // Zpracování zpráv ve worker vlákně
        // msg.what obsahuje identifikátor zprávy
        // msg.obj nebo msg.data mohou obsahovat data
        switch (msg.what) {
            case 1:
                // Zpracovat zprávu typu 1
                break;
            case 2:
                // Zpracovat zprávu typu 2
                break;
        }
    }
};

// Odeslání zprávy do worker vlákna
handler.sendEmptyMessage(1);

// Nebo provedení Runnable
handler.post(new Runnable() {
    @Override
    public void run() {
        // Kód, který se má vykonat ve worker vlákně
    }
});

// Když vlákno již není potřeba, ukončíme Looper a vlákno
handlerThread.quitSafely();