0

I have a fragment that displays weather data that runs a background thread that essentially just calls a function in my main UI to check whether my forecast is still valid. This function updates the UI so I am using a Handler and posting a Runnable to the main thread, like so:

public class WaveFxListFragment extends Fragment implements
        LoaderManager.LoaderCallbacks<Cursor>, View.OnClickListener {

    // .....

    // handler for dealing with synchronising update thread with UI
    private Handler mHandler;
    private UpdateThread mUpdateThread;

    private class UpdateThread extends Thread {
        volatile boolean running = false;

        @Override
        public void run() {
            running = true;

            while (running) {
                // get main UI thread to perform update check:
                Log.d(TAG, "Handler is " + mHandler);
                mHandler.post(new Runnable() { // getting null pointer error here!
                    @Override
                    public void run() {
                        checkValidTime();
                    }
                });

                try {
                    Thread.sleep(1000); // sleep 1 second
                } catch (InterruptedException e) {
                    Log.d(TAG, "Thread was interrupted!");
                    e.printStackTrace();
                }
            }
        }
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Reuse existing handler:
        mHandler = getActivity().getWindow().getDecorView().getHandler();
    }

    @Override
    public void onResume() {
        super.onResume();
        // start update checker:
        mUpdateThread = new UpdateThread();
        mUpdateThread.start();
    }

    @Override
    public void onPause() { 
            // stop update thread
            Log.d(TAG, "Asking thread to stop");
            mUpdateThread.running = false;

            super.onPause();
    }
}

This works fine; the problem is when I change my screen orientation. The current activity gets destroyed and if the thread is running, it tries to post a Runnable to a UI thread that no longer exists. So, I put a running member variable in the UpdateThread class and set if to false when my activity goes calls onPause. However, even though I have set the UpdateThread.running variable to false, my thread still tries to post a Runnable, but the Handler is now null! It shouldn't get that far, but it is!

Am I doing this wrong? My log message "Asking thread to stop" gets printed out, so I know it is getting as far as setting running to false.

Can anyone offer an insight?

Thanks

ccbunney
  • 2,282
  • 4
  • 26
  • 42
  • 1
    mHandler = getActivity().getWindow().getDecorView().getHandler(); I think the error comes from here. – aran Apr 29 '13 at 22:02

1 Answers1

0

A few things that you can do to resolve this.

  1. Interrupt the thread after you set running to false. This should cause the thread to exit earlier, or at the very least for your error to appear earlier.

  2. Check that your handler is not null in your update thread, and set it to null in onPause.

  3. Move the assignment of mHandler to onResume to make sure that mHandler is valid when the update thread is called.

GalaJon
  • 346
  • 2
  • 4