Während @yydl einen überzeugenden Grund dafür angibt, warum die newInstance
Methode besser ist:
Wenn Android beschließt, Ihr Fragment später neu zu erstellen, wird der Konstruktor ohne Argumente Ihres Fragments aufgerufen. Das Überladen des Konstruktors ist also keine Lösung.
Es ist immer noch möglich, einen Konstruktor zu verwenden . Um zu sehen, warum dies so ist, müssen wir zuerst sehen, warum die obige Problemumgehung von Android verwendet wird.
Bevor ein Fragment verwendet werden kann, wird eine Instanz benötigt. Android ruft YourFragment()
(der Konstruktor ohne Argumente ) auf, um eine Instanz des Fragments zu erstellen. Hier wird jeder überladene Konstruktor, den Sie schreiben, ignoriert, da Android nicht wissen kann, welchen Sie verwenden sollen.
Während der Lebensdauer einer Aktivität wird das Fragment wie oben erstellt und von Android mehrmals zerstört. Dies bedeutet, dass Daten, die in das Fragmentobjekt selbst eingefügt werden, verloren gehen, sobald das Fragment zerstört wird.
Um dies zu umgehen, fordert Android Sie auf, Daten mit einem Bundle
(Aufruf setArguments()
) zu speichern , auf den dann zugegriffen werden kann YourFragment
. Argumente bundle
werden von Android geschützt und sind daher garantiert dauerhaft .
Eine Möglichkeit, dieses Bundle festzulegen, ist die Verwendung einer statischen newInstance
Methode:
public static YourFragment newInstance (int data) {
YourFragment yf = new YourFragment()
/* See this code gets executed immediately on your object construction */
Bundle args = new Bundle();
args.putInt("data", data);
yf.setArguments(args);
return yf;
}
Ein Konstruktor:
public YourFragment(int data) {
Bundle args = new Bundle();
args.putInt("data", data);
setArguments(args);
}
kann genau das gleiche tun wie die newInstance
Methode.
Dies würde natürlich fehlschlagen und ist einer der Gründe, warum Android möchte, dass Sie die newInstance
Methode verwenden:
public YourFragment(int data) {
this.data = data; // Don't do this
}
Zur weiteren Erklärung hier die Fragmentklasse von Android:
/**
* Supply the construction arguments for this fragment. This can only
* be called before the fragment has been attached to its activity; that
* is, you should call it immediately after constructing the fragment. The
* arguments supplied here will be retained across fragment destroy and
* creation.
*/
public void setArguments(Bundle args) {
if (mIndex >= 0) {
throw new IllegalStateException("Fragment already active");
}
mArguments = args;
}
Beachten Sie, dass Android darum bittet, dass die Argumente nur bei der Erstellung festgelegt werden, und garantiert, dass diese beibehalten werden.
BEARBEITEN : Wie in den Kommentaren von @JHH ausgeführt, stellt Java Ihrem Fragment keinen Standardkonstruktor ohne Argumente zur Verfügung, wenn Sie einen benutzerdefinierten Konstruktor bereitstellen, für den einige Argumente erforderlich sind . Dazu müssten Sie einen Konstruktor ohne Argumente definieren. Dies ist Code, den Sie mit der newInstance
Factory-Methode vermeiden können .
BEARBEITEN : Android erlaubt nicht mehr die Verwendung eines überladenen Konstruktors für Fragmente. Sie müssen die newInstance
Methode verwenden.