When you rotate your device, your Activity
will be destroyed and recreated. Part of this is destroying and recreating any Fragment
s that your Activity is hosting.
During the recreation step, the Android framework needs to instantiate a new instance of your Fragment
. By default, it does so by invoking your Fragment's no-argument constructor. This means that this constructor must (a) exist and (b) be public
.
This recreation of Fragments is triggered by the super.onCreate()
of your Activity.
The general recommendation is to create a newInstance()
factory method (as you have done), but to leave the default constructor alone (i.e., do not make it private
). Yes, this means that it is still possible for someone to call the constructor directly, which you don't want, but it is required if you don't want to get involved with FragmentFactory
.
Further questions from comments
Does it mean that in onCreate I should check if the container already contain a Fragment before adding and commiting? Because as I understand from you,the onCreate().super will restore the old Fragment.
My recommendation here is to only commit the Fragment transaction once, the first time your Activity starts up. Generally, this is achieved by checking that the savedInstanceState
Bundle is null before committing the transaction:
if (savedInstanceState == null) {
getSupportFragmentManager().beginTransaction()
.replace(R.id.foo, FooFragment.newInstance(...))
.commit();
}
Because your Fragments are part of the instance state of your Activity, any recreation (any time savedInstanceState
is not null
) will be handled for you automatically.
Why it is better In newInstance method to add the information that the Fragment needs to the Bundle and not to store them as a members(attributes) of the Fragment?
Everything comes back to the fact that the Android framework needs to create a new instance of your Fragment. If you simply have member fields on your Fragment that you set, the Android framework will not be aware of these and will have no way to save or restore them.
However, the arguments
Bundle is something that Android does know about. Arguments are considered part of the Fragment's instance state (and therefore part of the containing Activity's instance state), and will be automatically saved and restored. That is why you can only put certain types of data into the arguments
Bundle; Android only knows how to "write" and "read" certain types of data during this recreation process.