Why use newInstance for DialogFragment instead of the constructor?

rfgamaral picture rfgamaral · Dec 23, 2012 · Viewed 13.1k times · Source

Looking at the documentation of DialogFragment, one sees the static newInstance method to initialize a new alert dialog fragment. My question is, why not use a constructor to do so, like this:

public MyAlertDialogFragment(int title) {
    Bundle args = new Bundle();
    args.putInt("title", title);
    setArguments(args);
}

Isn't this exactly the same or does it differ somehow? What's the best approach and why?

Answer

GaRRaPeTa picture GaRRaPeTa · Jan 6, 2014

If you create a DialogFragment that receives objects through the constructor, you will have problems when android recreates your fragment. This is what will happen:

  1. your code creates the dialog calling the constructor you have created and passing some arguments as dependencies.
  2. your dialog runs, and uses the dependencies that you passed though the constructor
  3. the user closes the app
  4. time passes, and android kills the fragment to free memory
  5. the user opens the app again
  6. android will recreate your dialog, this time using the default constructor. No arguments will be passed!
  7. Your dialog will be in a undesired state. It may try to use instance variables that you expected to pass through the constructor, but as they are not there you'll get a null pointer exception.

To avoid this, you need not to rely on the constructor to establish the dependencies, but in in Bundles (arguments and saved instances). That may force you to implement Parcelable in some classes, which sucks.

EDIT: you can reproduce Android killing the app (step 4) by enabling the "don't maintain Activities" in the Development settings. That's the way to easily test it.