11

I usually delegate all Activities events to a separate controller class, which has a special method for handling events from Activity

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

This is done in order to keep UI thread responsive and make all computations in background tasks.

However, when Activity.onDestroy() method is called by the system, controller.dispose() method is called, which cleans up all stuff in controller this way

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

As you can see, disposing of controller happens in UI thread, without delegating it to a handler thread.

The problem happens when, for example, onDestroy is called in the middle of onStartup() method: onDestroy cleans up the model and all other references, but inside onStartup method it tries to access the model at some point, but considering it is null, an exception is thrown.

What is the best way for resolving this issue? I do not want to lock every controller method because some of them may happen simultaneously without interfering each other.

andersoj
  • 22,406
  • 7
  • 62
  • 73
Sergei Ledvanov
  • 2,131
  • 6
  • 29
  • 52
  • Moreover, it is possible that onDestroy method is not called by the system. – Yury Mar 06 '12 at 18:18
  • Good point Yuri, but if it's not called, then all objects allocated by the activity are destroyed by JVM themself? So I do not have to worry about it, right? In dispose I have only disposing of all objects, nothing else. – Sergei Ledvanov Mar 08 '12 at 09:03

1 Answers1

6

In the dispose() method you should cleanup the workerHandler before disposing of the model. See the removeCallbacks or removeCallbacksAndMessage(null) methods in the Handler class. The latter method removes all callbacks and messages when the argument is null.

Martin Serrano
  • 3,727
  • 1
  • 35
  • 48
  • workerHandler is type of Handler. How can I cancel all runnables that were added to this Handler using post() method? – Sergei Ledvanov Sep 24 '12 at 06:54
  • yes, but this means that I need to track all callbacks I add, otherwise I do not know what callbacks should I remove. There's no mehtod like "removeAllCallbacks()" or something. I should then have a list like `List` and store all runnables there. – Sergei Ledvanov Sep 25 '12 at 05:42