Mam Fragment
konstruktora, który przyjmuje wiele argumentów. Moja aplikacja działała dobrze podczas programowania, ale podczas produkcji moi użytkownicy czasami widzą tę awarię:
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
Mógłbym stworzyć pustego konstruktora, jak sugeruje ten komunikat o błędzie, ale to nie ma dla mnie sensu, ponieważ musiałbym wtedy wywołać osobną metodę, aby zakończyć konfigurację Fragment
.
Jestem ciekawy, dlaczego ta awaria zdarza się tylko czasami. Może używam ViewPager
niewłaściwie? Sam tworzę instancję wszystkich Fragment
i zapisuję je na liście w pliku Activity
. Nie używam FragmentManager
transakcji, ponieważ ViewPager
przykłady, które widziałem, nie wymagały tego i wszystko wydawało się działać podczas programowania.
android
android-fragments
stkent
źródło
źródło
Fragment
podklasa w ogóle nie deklaruje żadnych konstruktorów, domyślnie zostanie utworzony dla ciebie pusty konstruktor publiczny (jest to standardowe zachowanie Java ). Zdajesz nie trzeba jawnie deklarować pusty konstruktor chyba deklaruje innych konstruktorów (np te z argumentów).Odpowiedzi:
Tak, robią.
Zresztą nie powinieneś tak naprawdę nadpisywać konstruktora. Powinieneś mieć
newInstance()
zdefiniowaną metodę statyczną i przekazać dowolne parametry za pomocą argumentów (pakiet)Na przykład:
I oczywiście chwytanie argumentów w ten sposób:
Następnie utworzyłbyś instancję z menedżera fragmentów w następujący sposób:
W ten sposób po odłączeniu i ponownym podłączeniu stan obiektu można zapisać za pomocą argumentów. Podobnie jak pakiety dołączone do Intentów.
Powód - dodatkowe czytanie
Myślałem, że wyjaśnię, dlaczego ludzie zastanawiają się, dlaczego.
Jeśli zaznaczysz: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/app/Fragment.java
Zobaczysz
instantiate(..)
metodę wFragment
klasie wywołującąnewInstance
metodę:http://docs.oracle.com/javase/6/docs/api/java/lang/Class.html#newInstance () Wyjaśnia, dlaczego po utworzeniu instancji sprawdza, czy jest to akcesor
public
i czy moduł ładujący klasy umożliwia mu dostęp.W sumie jest to dość paskudna metoda, ale pozwala
FragmentManger
zabijać i odtwarzaćFragments
ze stanami. (Podsystem Android robi podobne rzeczyActivities
).Przykładowa klasa
Często pytano mnie o telefonowanie
newInstance
. Nie należy tego mylić z metodą klasową. Ten przykład całej klasy powinien pokazywać użycie.źródło
Jak zauważył CommonsWare w tym pytaniu https://stackoverflow.com/a/16064418/1319061 , ten błąd może również wystąpić, jeśli tworzysz anonimową podklasę fragmentu, ponieważ anonimowe klasy nie mogą mieć konstruktorów.
Nie twórz anonimowych podklas Fragmentu :-)
źródło
Tak, jak widać, pakiet wsparcia tworzy również fragmenty (gdy zostaną zniszczone i ponownie otwarte). Twoje
Fragment
podklasy potrzebują publicznego pustego konstruktora, ponieważ tak nazywa się framework.źródło
super()
byłyby bezowocne, ponieważ klasa nadrzędna złamała regułę pustego konstruktora publicznego. Więc nie, nie musisz przechodzićsuper()
do swojego konstruktora.Oto moje proste rozwiązanie:
1 - Zdefiniuj swój fragment
2 - Utwórz nowy fragment i wypełnij parametr
3 - Ciesz się!
Oczywiście możesz zmienić typ i liczbę parametrów. Szybko i łatwo.
źródło