Android - Konstruktor aktywności a onCreate

88

Rozumiem, że Android Activitiesma określone cykle życia i onCreatenależy to zastąpić i użyć do inicjalizacji, ale co dokładnie dzieje się w konstruktorze? Czy są jakieś przypadki, w których można / należy również zastąpić Activitykonstruktora, czy też nie należy go nigdy dotykać?

Zakładam, że konstruktor nigdy nie powinien być używany, ponieważ odwołania do Activitiesnie są całkowicie oczyszczone (w ten sposób utrudniają działanie modułu odśmiecającego) i to onDestroyjest w tym celu. Czy to jest poprawne?

ubóstwiać
źródło
2
A co z faktem, że Android może zniszczyć / odtworzyć Twoją aktywność w dowolnym momencie? Nie wiadomo, czy wtedy zostanie wywołany konstruktor, a nawet jeśli - który konstruktor zostanie wywołany ... (to samo dotyczy fragmentów i dlatego każdy fragment musi implementować pusty domyślny konstruktor).
Marian Paździoch

Odpowiedzi:

34

Nie przychodzi mi do głowy żaden dobry powód, żeby cokolwiek robić w konstruktorze. Nigdy nie konstruujesz działania bezpośrednio, więc nie możesz go użyć do przekazania parametrów. Ogólnie rzecz biorąc, po prostu rób rzeczy w onCreate.

Cheryl Simon
źródło
73
onCreate () zapobiega używaniu końcowych pól.
Gili
2
Ale OnCreate nie jest wywoływany tylko raz, czy się mylę? Kiedy zmieniam orientację ekranu i
cofam się
2
Wydaje mi się, że @fercis onCreate jest wywoływane tylko raz na instancję. Podczas obracania urządzenia ta instancja działania jest niszczona i tworzony jest nowy, wywołujący onCreate. To powiedziawszy, jestem prawie pewien, że nie możesz utworzyć instancji końcowych pól w onCreate, ponieważ Java nie wie, że onCreate zostanie wywołane tylko raz (i rzeczywiście, możesz wywołać to ponownie samodzielnie w swoim kodzie - zdarzają się złe rzeczy, ale nadal będzie się kompilować), więc jedynym sposobem na utworzenie instancji pól końcowych byłby konstruktor.
Harvey Adcock
Kiedy dokładnie zaczyna działać zdarzenie OnCreate? Kiedy ustawię punkt przerwania na początku zdarzenia OnCreate, aby aplikacja działała i ładowała aktywność na ekran, aktywuje się punkt przerwania, a aplikacja przechodzi do wstrzymania. Potrzebuję zdarzenia dotyczącego działania, które jest aktywowane dokładnie przed zainicjowaniem i uruchomieniem działania.
Mohammad Afrashteh
@Cheryl Simon, Powiedziałeś, że nigdy nie tworzysz działania bezpośrednio, więc kto je tworzy?
Sreekanth Karumanaghat,
7

Dobrym powodem umieszczania rzeczy w konstruktorze, jak stwierdził komentarz Gili, jest użycie końcowych pól.

Jeśli jednak zainicjujesz rzeczy w konstruktorze, żywotność obiektu będzie trochę dłuższa, chociaż nie myślę o tym zbyt wiele, ponieważ onCreatezostanie wywołany wkrótce potem.

Mimo to wbrew moim ideałem, mam unikać konstruktora do inicjalizacji członków aktywności i polegać na onResume()i onPause()zasobów, że moja aplikacja do czynienia.

Dla onCreate()Zwykle używam go zrobić widok mapowanie do zmiennych lokalnych. Chociaż adnotacje na Androida już to robią, rzadko mam onCreate()metodę dla mojej aktywności. Jednak nadal używam go w usłudze.

Jeśli jednak spojrzysz na członków, być może inicjujesz

  • mieliby metodę „zamknij”, którą należy wywołać we właściwym czasie (onResume lub onPause)

  • byłyby częścią widoku, co oznacza, że ​​należy go zainicjować, a następnie wywołać onCreate

  • są to stałe, których i tak nie trzeba umieszczać w konstruktorze, wystarczyłoby tylko statyczne zakończenie. Obejmuje to stałe Paint i Path, które mogą być inicjowane przez blok statyczny

Archimedes Trajano
źródło
1
Co masz na myśli mówiąc, że żywotność przedmiotu będzie trochę dłuższa? W jaki sposób? Ponieważ na przykład przeniesienie tych inicjalizacji do onCreate nadal zajmuje tyle samo czasu. Nie ma różnicy w długości życia, którą mogę określić. Czy możesz szerzej to rozwinąć, ponieważ czuję, że jako względnie nowicjusz mogę przegapić coś kluczowego.
RichieHH
2
@RichieHH przez dłuższy Archimedes mówi tylko, że konstruktor zostanie wywołany przed onCreate (), więc cokolwiek zostanie tam zrobione, będzie trwać (nieco) dłużej niż w przeciwnym razie do czasu zniszczenia aktywności
pho79
6

Jestem teraz w sprawie, która musi zastąpić konstruktora. W rzeczywistości mam kilka działań, które mają taką samą strukturę. Więc zamiast tworzyć wiele działań, utworzę jedno działanie „nadrzędne”, a pozostałe odziedziczą to. Dlatego muszę przesłonić konstruktora działania podrzędnego, aby móc zainicjować niektóre zmienne, które będą używane w metodach oncreate.

W dwóch słowach, konstruktor sprawia, że ​​symulujesz „działanie nadrzędne”, które można ponownie wykorzystać w drodze dziedziczenia!

biboMandroid
źródło
15
Wiem, że to jest stare, ale jaka jest korzyść z samego zaimplementowania w nim instancji super pola onCreate (). I tak będziesz wywoływał super.onCreate () od dziecka.
Andrew G
Więc po prostu przekazując różne wartości do tego samego KEY w pakiecie lub intencji podczas uruchamiania działania, a tym samym używając tego samego działania, możesz określić, co ma być wyświetlane w działaniu w zależności od otrzymanej wartości. Jaki jest konkretny powód, dla którego wybrałeś konstruktorów? Albo utrzymując niezmienną część Aktywności jako wspólną, a przez resztę zmieniającej się części można było utworzyć Fragmenty.
Nayanesh Gupte
0

Musisz nadpisać Konstruktora, gdy twoje działanie będzie miało niestandardowe parametry lub chcesz śledzić wywołania z klas, które odziedziczyły.

Pentium10
źródło
1
Czy możesz to rozwinąć bardziej? To, co opisujesz, brzmi interesująco, ale jest trochę niejasne. Dzięki!
idolize
3
Załóżmy, że musisz utworzyć niestandardową klasę Activity, która przyjmuje 2 lub więcej parametrów. Musisz tylko użyć Konstruktora, nie możesz tego zrobić za pomocą onCreate i dodatków. Czy to pomaga?
Pentium10
1
Może potrzebuję prywatnego. Załóżmy, że chcę utworzyć komponent niestandardowy, na przykład niestandardowy selektor kontaktów. Aby to mieć startActivityForResult, muszę dołączyć prywatnego konstruktora do mojego komponentu niestandardowego, nawet jeśli ta aktywność nigdy nie zostanie uruchomiona i nie ma widocznych elementów, po prostu używam jej jako wyniku.
Pentium10,
6
Powiem, że nie ma to dla mnie sensu @Pentium, nie bez przykładu kodu.
Blundell,
Myślę, że jedną z zalet robienia rzeczy za pomocą konstruktora jest posiadanie działania „szablonu”, które może przyjmować parametry, z których może korzystać dziedziczona klasa. Na przykład, jeśli masz dwie aktywności, które różnią się tylko niektórymi właściwościami, np. R.id.cameraSurface, R.id.videoSurface, możesz utworzyć konstruktora, który przyjmie parametr o nazwie AbstractResourceActivity, a następnie masz CameraActivity, który jest zarejestrowany w manifeście, który rozszerza AbstractResourceActivity przekazujący identyfikator zasobu.
Archimedes Trajano,