2013-08-13 11 views
6

Używam obiektu handler do kontynuowania pracy interfejsu użytkownika po zakończeniu czasochłonnego zadania w osobnym wątku. Miałem problem z powyższym ostrzeżeniem Linta i podążaniem za moim podejściem.Android Threading: Ta klasa programu Handler powinna być statyczna lub mogą wystąpić przecieki

[Próbka Handler Obiekt 1] ->

Handler responseHandler = new Handler() 
{ 
    @Override 
    public void handleMessage(Message msg) 
    { 
     super.handleMessage(msg); 
     Toast.makeText(MainActivity.this, "Finished the long running task in seperate thread...", Toast.LENGTH_LONG).show(); 
    }  
}; 

[Próbka Handler Obiekt 2] ->

Handler responseHandler = new Handler(new Handler.Callback() 
{  
    @Override 
    public boolean handleMessage(Message msg) 
    { 
     Toast.makeText(MainActivity.this, "Finished long running task in a seperate thread...", Toast.LENGTH_LONG).show(); 
     return false;  // RETURN VALUE ???? 
    } 
}); 

W oddzielnym wątek (inny niż interfejs użytkownika) wh Aby wykonać czasochłonne zadanie, wykonuje on następującą linię, aby przywrócić kontrolę do wątku interfejsu użytkownika (w zasadzie do obsługi obiektu).

responseHandler.sendEmptyMessage(0); 

Program działa bardzo dobrze z obu typów obiektów procedur obsługi, ale z 1 typu I otrzymuję ostrzeżenie Lint mówiąc klasa ta Handler powinny być statyczne lub przecieki mogą wystąpić.

Dlatego zacząłem używać drugiego rodzaju obiektu obsługi, aby uniknąć ostrzeżenia o Lintach, ale problem, który mam, to, nie jestem pewien co do znaczenia wartości zwracanej (prawda/fałsz) w 2 sposób i również działa z jednym z nich. Szukałem tego w Google na tyle, ale nie dostałem dokładnej odpowiedzi wyjaśnił tę wartość zwrotu.

Tak, widziałem to pytanie zadawano w wielu miejscach w stackoverflow głównie regrding ostrzeżenie Lint, ale moje pytanie dotyczy głównie typu zwrotu w 2 sposób i aby go potwierdzić, czy jest to w porządku sposób rozwiązać problem używając drugiego rodzaju obsługi Obj.

pytania ->

1). Czy ktoś wie, co to jest za wartość (prawda/fałsz)?

2). Czy to jest właściwa rzecz, którą zrobiłem, aby pozbyć się ostrzeżenia o lintach?

Dzięki ...

+0

Tak, sprawdź załączony wpis. –

+0

Widziałem te linki, a moje pytanie dotyczy głównie wartości zwrotu, w której nie znalazłem wyjaśnienia. – JibW

+0

http://stackoverflow.com/questions/17899328/this-handler-class-should-be-static-lub-leaks-might-occur-com-test-test3-ui-main/17899429#17899429. sprawdź to i to https://groups.google.com/forum/#!topic/android-developers/1aPZXZG6kWk. sprawdź dyskusję na temat i rozwiązanie przez Romaina. – Raghunandan

Odpowiedz

1

znalazłem kilka ważnych informacji o wycieku pamięci przez wewnętrzne klasy jak przewodnika i chcą podzielić się z wami:

How to Leak a Context: Handlers & Inner Classes I myślę, że zastąpiona metoda klasy Handler niczego nie wrócić jak można sprawdzić: handleMessage()

masz nadpisane klasa Java Android Handler Handler nie widać handleMessage() klasy Java Handler jest posiadanie instrukcji return i można sprawdzić przyczynę również dla instrukcji return tutaj: boolean handleMessage(C context)

5

Każdy program obsługi jest powiązany z Looper wątku, każdy Message jest umieszczony na strukturze danych, kolejce komunikatów.

Message ma target zmienną wskazującą na Handler, a callback zmiennej, która wskazuje na Runnable.

Tak więc, jeśli używasz klasy anonimowej do utworzenia obiektu Handler (jak w pierwszym przykładzie), to wiedz, że anonimowe/niestatyczne klasy wewnętrzne zawierają odniesienie do obiektów zewnętrznych (Activity?). Tak więc wiadomość umieszczona w kolejce może zawierać odniesienia do Handler jako celu, a Handler z kolei zawiera odniesienie do klasy zewnętrznej, na przykład Activity.

Teraz wiadomość może pozostać w kolejce komunikatów przez długie okresy czasu, o ile wątek jest uruchomiony. Tymczasem działalność mogła zostać odrzucona. Ale to nie będą śmieci zebrane z powodu niejasnego pośredniego odniesienia, które ma wiadomość. Zwróć uwagę, że Looper i Message Queue pozostają tak długo, jak długo wątek jest uruchomiony.

W drugim przykładzie nie tworzysz anonimowej klasy Handler. Używasz konstruktora obsługi i przekazujesz mu anonimowy obiekt Callback. To może powstrzymać Linta od narzekania, ale wątpię, czy to dobre podejście. Po prostu unikaj klas wewnętrznych, unikaj przekazywania aktywności lub odniesień kontekstowych do Handler'a.

Aktualizacja:

przewodnika dispatchMessage() dostaje wiadomości z powodu przetworzenia, gdzie sprawdza, czy zwrotna została dostarczona, wówczas jeśli zwrotna jest zapewnione, że nie zwraca handleMessage(), jeśli funkcja zwrotna za handleMessage() zwraca true :

public void dispatchMessage(Message msg) { 
    if (msg.callback != null) { 
     handleCallback(msg); 
    } else { 
     if (mCallback != null) { 
      if (mCallback.handleMessage(msg)) { 
       return; 
      } 
     } 
     handleMessage(msg); //--won't be called if you return true. 
    } 
} 
Powiązane problemy