Остановка запускаемых задач обработчиком при уничтожении активности - PullRequest
11 голосов
/ 06 марта 2012

Я обычно делегирую все события Деятельности отдельному классу контроллера, у которого есть специальный метод для обработки событий от Activity

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

Это сделано для того, чтобы обеспечить поддержку потока пользовательского интерфейса и сделать все вычисления в фоновых задачах.

Однако, когда система вызывает метод Activity.onDestroy(), вызывается метод controller.dispose(), который таким образом очищает все содержимое контроллера

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

Как вы можете видеть, удаление контроллера происходит в потоке пользовательского интерфейса, без передачи его в поток обработчика.

Проблема возникает, когда, например, onDestroy вызывается в середине метода onStartup(): onDestroy очищает модель и все другие ссылки, но внутри метода onStartup он пытается получить доступ к модели в какой-то момент, но, учитывая, что это null, выдается исключение.

Как лучше всего решить эту проблему? Я не хочу блокировать каждый метод контроллера, потому что некоторые из них могут происходить одновременно, не мешая друг другу.

1 Ответ

6 голосов
/ 21 сентября 2012

В методе dispose () вы должны очистить workerHandler перед удалением модели.См. Методы removeCallbacks или removeCallbacksAndMessage (null) в классе Handler.Последний метод удаляет все обратные вызовы и сообщения, когда аргумент null.

...