2012-03-06 14 views
8

zwykle delegować wszystkich działań zdarzenia do osobnej klasy kontrolera, który posiada specjalną metodę obsługi zdarzeń z ActivityZatrzymywanie Handler przypisanymi zadaniami, gdy niszczy aktywność

@Override 
public boolean handleMessage(int what, Object data) { 
    switch (what) { 
    case ExerciseViewEvent.STARTUP: 
     workerHandler.post(new Runnable() { 
      public void run() { 
       onStartup(); 
      } 
     }); 
     return true; 
} 

Odbywa się to w celu utrzymania wątku UI elastyczne i wszystkie obliczenia wykonuj w tle.

Jednak gdy Activity.onDestroy() metoda jest wywoływana przez system, controller.dispose() wywoływana jest metoda, która sprząta wszystko rzeczy w kontrolerze tędy

@Override 
protected synchronized void dispose() { 
    ................. 
    if (model != null) { 
     synchronized (model) { 
      model.dispose(); 
     } 
     model = null; 
    } 
    helper = null; 
    ..................... 
    super.dispose(); 
} 

Jak widać, usuwania sterownika dzieje się w wątku UI, bez delegowanie go do wątku obsługi.

Problem dzieje, kiedy, na przykład, onDestroy nazywany jest w środku onStartup() metody: onDestroy sprząta model i wszystkie inne odniesienia, ale wewnątrz onStartup metody próbuje uzyskać dostęp do modelu w pewnym momencie, ale biorąc pod uwagę, że jest null, zgłoszony wyjątek.

Jaki jest najlepszy sposób rozwiązania tego problemu? Nie chcę blokować każdej metody kontrolera, ponieważ niektóre z nich mogą się zdarzyć jednocześnie, bez wzajemnego zakłócania się.

+0

Co więcej, możliwe jest, że metoda onDestroy nie jest wywoływana przez system. – Yury

+0

Dobra racja, Yuri, ale jeśli nie jest wywołana, to wszystkie obiekty przydzielone przez działanie są niszczone przez same JVM? Więc nie muszę się tym martwić, prawda? W dyspozycji mam tylko pozbywanie się wszystkich przedmiotów, nic więcej. –

Odpowiedz

4

W metodzie dispose() należy oczyścić workerHandler przed pozbyciem się modelu. Zobacz metody removeCallbacks lub removeCallbacksAndMessage(null) w klasie Handler. Ta ostatnia metoda usuwa wszystkie wywołania zwrotne i wiadomości, gdy argumentem jest null.

+0

workerHandler jest typu Handler. Jak mogę anulować wszystkie gry, które zostały dodane do tego Handler za pomocą metody post()? –

+0

Dodałem link w odpowiedzi –

+0

tak, ale oznacza to, że muszę śledzić wszystkie wywołania zwrotne, które dodaję, w przeciwnym razie nie wiem, jakie połączenia zwrotne należy usunąć. Nie ma taktu jak "removeAllCallbacks()" czy coś takiego. Powinienem wtedy mieć listę taką jak "List " i przechowywać tam wszystkie runnable. –