androidandroid-fragmentsandroid-thread

App randomly crashes when starting background thread of a fragment


I have this code for my fragment:

public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    txtAngle = view.findViewById(R.id.textView_angle);

    updateTextThread = new Thread(new Runnable() {
        @Override
        public void run() {
            while (threadRunning) {
                txtAngle.setText("1");
            }
        }
    });

    threadRunning = true;
    updateTextThread.start();
}

@Override
public void onDestroyView() {
    super.onDestroyView();
    binding = null;
    threadRunning = false;
}

The app works fine the first time I navigate to this fragment, but if I return to the main page and navigate to this fragment again, the app has a 30% chance to crash, throwing java.lang.NullPointerException: Attempt to invoke virtual method 'int android.text.Layout.getWidth()' on a null object reference for the setText line of the thread. I tried to use Thread.interrupt() to stop the thread but it didn't work.

So what caused the crash and how can I solve it?


Solution

  • You should take care ot two things here :

    1. sharing a variable between two threads
    2. updating UI out of the render thread / main thread

    What you should do :

    use thread safe variables like AtomicBoolean or a volatile boolean for the threadRunning var... and a double checked locking or a Lock for verifying the value of the var

    without this you have no guarantee that you update thread loop is not before the setText method when changing the threadRunning var value...

    also, you'd better call super.onDestroyView() at the end of the onDestroyView method.

    What you could do :

    Dispatch the TextView update from the update thread to the main thread using one of the following possibility (not exhaustive)