2013-07-05 10 views
6

musiałem dodać Looper do następującego kodu:Zrozumienie tego, co jest o Looper w Androidzie

public class MyRunnable implements Runnable 
{ 
    @Override 
    public void run() 
    { 
     Looper.prepare(); 
     final Looper looper = Looper.myLooper(); 

     new Handler().postDelayed(
      new Runnable() 
      { 
      @Override 
      public void run() 
      { 
       try 
       { 
       } 
       catch (Exception ex) 
       { 
       } 
       finally 
       { 
       looper.quit(); 
       } 
      } 
      }, 100); 

     Looper.loop(); 
    } 
} 

Zauważ, że mam runnable Wewnątrz runnable. Zagnieżdżony runnable zostaje wykonany za pomocą Handler'a. Początkowo nie miałem Loopera, ale Android narzekał, że muszę zadzwonić Looper.prepare przed wykonaniem kolejnego wątku.

Przeczytałem na Looperie, ale nadal wydaje się to dość zagadkowe. Wygląda na to, że działa jak rodzaj wewnętrznego przesyłania komunikatów. Nie jest dla mnie jasne, dlaczego jest to konieczne, ponieważ nie ma żadnych wiadomości, które przechodzą od mojego zewnętrznego działania do mojego wewnętrznego działania. Nawet jeśli to prawda, wygląda na to, że Android po prostu tworzy twardą regułę, że jeśli wywołujesz wątek z wątku, MUSISZ również wywołać Looper.prepare. Nawet jeśli zaakceptuję to jako takie, to nadal nie pomoże mi zrozumieć, dlaczego muszę wywołać looper.loop i looper.quit. Jeśli pominę Looper.loop, mój Handler nigdy nie działa, a to nie jest jasne. Co robi Looper.loop, który pozwala uruchomić mój Handler?

+1

możliwy duplikat [android: jaki jest cel Looper i jak go używać?] (Http://stackoverflow.com/questions/7597742/android-what-is-the- purpose-of-looper-and -Jak tego użyć). Tak, jeśli chcesz użyć Looper, musisz zadzwonić do Looper.prepare(). Alternatywami do używania Looper'a są po prostu tworzenie normalnych (równoległych) wątków lub używanie AsyncTasks. Przeczytaj link SO, o którym wspomniałem, aby uzyskać nieco więcej informacji. "Mam nadzieję, że pomaga ... – paulsm4

+0

Rodzaj wyjaśnia to. Największy problem, jaki widzę, odnosi się do Runnables jako "wiadomości". Nie są to "wiadomości" w tradycyjnym rozumieniu świata programowania, ponieważ Runnable to wykonywalna część kodu, a nie tylko dane zawierające wiadomość. Co więcej, przykład, który wskazałeś, nie zawiera nawet looper.quit, który jest wymagany, ani nie wskazuje, że Looper.loop będzie blokował się w nieskończoność aż do wywołania looper.quit. Looper powinien być zdefiniowany jako kolejka do wykonywania wielu Runnables. – AndroidDev

Odpowiedz

8

Oto wspaniały artykuł na ten temat.

Looper and Handler in Android

To przychodzi wraz z prostym schemacie, który prowadzi do prostego rozumienia relacji między Loopers i Handler.

Na tym schemacie widzimy, że obrębie tego samego wątku (przedstawionym przez wielki prostokąt), bez względu na to ile obsługi tworzyć, będą być w całości przy użyciu tego samego Looper, czyli wyjątkowy looper tego wątku.

Handlers & Loopers

Uwaga:

Looper być prepared aby umożliwić powiązanych obsługi przetwarzania posted messages.

Aplikacja Android, a dokładniej, wątek UI aplikacji dla systemu Android (główny wątek), jest już dostarczany z przygotowanym chwytaczem (mainLooper).

Oto jak wykonać Communicating with the UI Thread.

4

Prosta koncepcja chwytacza:

  1. Każda nitka pracownik utworzyć i kończy bieg raz wykonuje on swoją ostatnią operację.

  2. Aby zapobiec zakończeniu wątku, można uruchomić pętlę, dzwoniąc pod numer Looper.loop(), uważając ją za instrukcję while(true){}. Przed wywołaniem Looper.loop() musisz przygotować pętlę z Looper.prepare(), jeśli nie jest jeszcze przygotowany. Aby zakończyć pętlę i zakończyć wątek, musisz zadzwonić pod numer looper.quit() na looper.

Teraz powiadomienia dostałeś od Androida:

Podczas tworzenia Handler w wątku, to będzie zobowiązany do wątku jest utworzony i kiedy piszesz uruchamianego za pomocą tego Handler, kod działa na wątku Handler'a.

Kiedy system wykrył, że chcesz uruchomić kod (w szczególności 100ms w przyszłości) na uchwycie, który jest powiązany z wątkiem, który zginie zaraz po zakończeniu wywoływania metody post, zaproponował użycie Looper.loop() aby zapobiec zakończeniu tego wątku i tym samym umożliwić prawidłowe uruchomienie drugiego Runnable w wciąż istniejącym wątku.

Powiązane problemy