Ich habe einen Fragment
mit einem Konstruktor, der mehrere Argumente akzeptiert. Meine App hat während der Entwicklung gut funktioniert, aber in der Produktion sehen meine Benutzer manchmal diesen Absturz:
android.support.v4.app.Fragment$InstantiationException: Unable to instantiate fragment
make sure class name exists, is public, and has an empty constructor that is public
Ich könnte einen leeren Konstruktor erstellen, wie diese Fehlermeldung andeutet, aber das macht für mich keinen Sinn, da ich seitdem eine separate Methode aufrufen müsste, um die Einrichtung des zu beenden Fragment
.
Ich bin gespannt, warum dieser Absturz nur gelegentlich vorkommt. Vielleicht benutze ich das ViewPager
falsch? Ich instanziiere alle Fragment
s selbst und speichere sie in einer Liste innerhalb der Activity
. Ich verwende keine FragmentManager
Transaktionen, da die ViewPager
Beispiele, die ich gesehen habe, dies nicht erforderten und alles während der Entwicklung zu funktionieren schien.
quelle
Fragment
Unterklasse überhaupt keine Konstruktoren deklariert, wird standardmäßig implizit ein leerer öffentlicher Konstruktor für Sie erstellt (dies ist das Standardverhalten von Java ). Sie nicht müssen explizit einen leeren Konstruktor deklarieren , wenn Sie auch andere Konstrukteure (zB solche mit Argumenten) erklärt.Antworten:
Ja, das tun sie.
Sie sollten den Konstruktor sowieso nicht wirklich überschreiben. Sie sollten eine
newInstance()
statische Methode definiert haben und alle Parameter über Argumente (Bundle) übergeben.Beispielsweise:
Und natürlich die Argumente so packen:
Dann würden Sie von Ihrem Fragmentmanager aus wie folgt instanziieren:
Auf diese Weise kann der Objektstatus über die Argumente gespeichert werden, wenn er getrennt und erneut angehängt wird. Ähnlich wie Bündel, die an Absichten befestigt sind.
Grund - Zusätzliche Lektüre
Ich dachte, ich würde erklären, warum für Leute, die sich fragen, warum.
Wenn Sie Folgendes überprüfen: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/Fragment.java
Sie werden sehen, dass die
instantiate(..)
Methode in derFragment
Klasse dienewInstance
Methode aufruft :http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#newInstance () Erklärt, warum bei der Instanziierung überprüft wird, ob der Accessor vorhanden ist
public
und ob dieser Klassenladeprogramm den Zugriff darauf zulässt.Alles in allem ist es eine ziemlich böse Methode, aber sie erlaubt
FragmentManger
es,Fragments
mit Zuständen zu töten und neu zu erschaffen . (Das Android-Subsystem macht ähnliche Dinge mitActivities
).Beispielklasse
Ich werde oft gefragt, ob ich anrufen soll
newInstance
. Verwechseln Sie dies nicht mit der Klassenmethode. Dieses ganze Klassenbeispiel sollte die Verwendung zeigen.quelle
Wie von CommonsWare in dieser Frage https://stackoverflow.com/a/16064418/1319061 festgestellt , kann dieser Fehler auch auftreten, wenn Sie eine anonyme Unterklasse eines Fragments erstellen, da anonyme Klassen keine Konstruktoren haben können.
Erstelle keine anonymen Unterklassen von Fragment :-)
quelle
Ja, wie Sie sehen, instanziiert das Support-Paket auch die Fragmente (wenn sie zerstört und wieder geöffnet werden). Ihre
Fragment
Unterklassen benötigen einen öffentlichen leeren Konstruktor, da dies vom Framework aufgerufen wird.quelle
super()
wäre erfolglos, da die übergeordnete Klasse die Regel des leeren öffentlichen Konstruktors verletzt hat. Also nein, Sie müssen nichtsuper()
in Ihrem Konstruktor übergeben.Hier ist meine einfache Lösung:
1 - Definieren Sie Ihr Fragment
2 - Erstellen Sie Ihr neues Fragment und füllen Sie den Parameter aus
3 - Genieße es!
Natürlich können Sie den Typ und die Anzahl der Parameter ändern. Schnell und einfach.
quelle