Android: kiedy onCreateOptionsMenu jest wywoływane podczas cyklu życia działania?


149

Wstawiłem kilka punktów przerwania onCreate(jeden na początku i jeden na końcu metody), a także jeden na początku onCreateOptionsMenu. onCreateMetoda nazywa się pierwszy, a przed jej zakończeniem onCreateOptionsMenujest tzw.

Próbuję oddzielić Fragmentkod nawigacji w mojej aplikacji, więc mam kilka obiektów, do których deleguję, onCreateOptionsMenuw zależności od tego, czy aplikacja działa na telefonie / tablecie (używam rozmiaru ekranu, aby to określić, mój plik układu dla duże ekrany mają Widok, który sprawdzam po zawyżeniu układu). Problem polega na tym, że tworzę te obiekty w onCreate i otrzymuję wyjątek zerowego wskaźnika, gdy odwołuję się do obiektu w onCreateOptionsMenu.

Odpowiedzi:


112

Najpierw wywoływana jest metoda onCreate, a przed zakończeniem wywoływana jest metoda onCreateOptionsMenu.

Będzie to prawdą na urządzeniach i aplikacjach z oficjalnym paskiem akcji w stylu plastra miodu. Jeśli nie ma paska akcji, onCreateOptionsMenu()nie powinien być wywoływany, dopóki użytkownik nie otworzy menu, zwykle naciskając przycisk MENU.

(Używam rozmiaru ekranu, aby to określić, mój plik układu dla dużych ekranów ma widok, który sprawdzam po zawyżeniu układu)

Ten test zakończy się bardzo szybko, gdy zostanie wysłany Ice Cream Sandwich. Z tego, co wiem, telefony ICS będą miały paski akcji (choć może nie paski systemowe).


Zapomniałem wspomnieć, że używam biblioteki ActionbarSherlock. Twoja odpowiedź przypomniała mi. Prawdopodobnie jest to przyczyną tego zachowania, ponieważ jest to opakowanie w bibliotece zgodności, która umieszcza elementy menu w „ActionBar”.
Christopher Perry,

@commonsware - oznacza to na urządzeniach i aplikacjach, które nie mają paska akcji. Menu pojawi się, nawet jeśli onCreateOptionsMenu nie ma widocznego elementu?
NinjaCoder

12
W moim przypadku onCreateMenu rozmowy po onResume
Kostia Khuta

1
Tak, mam ten sam problem ... Ale mój kod jest powiązany z fragmentem.
Yoann Hercouet

Zacząłem mieć NPE, sprawdzając, czy nav drawer fragmentjest otwarty w onCreateOptionsMenu. Musiałem umieścić null sprawdzenia zarówno w onCreateOptionsMenu działania, jak i wywołaniu zwrotnym, którego fragment używał w swoim onCreateOptionsMenu. Naprawdę dziwne, ponieważ działo się to tylko na kilku ekranach, ale konsekwentnie na tych.
theblang

54

W moim przypadku na Androidzie 2.3 iz FragmentActivitybiblioteką obsługującą v4 kolejność wywołań metod cyklu życia jest następująca:

07-18 18:29:21.629  20183-20183/? I/onCreate:
07-18 18:29:21.719  20183-20183/? I/onStart: 
07-18 18:29:21.719  20183-20183/? I/onResume: 
07-18 18:29:21.739  20183-20183/? I/onCreateOptionsMenu:

27

Znalazłem, jeśli w onResume () dzwonię

invalidateOptionsMenu();

następnie onCreateOptionsMenu (menu menu) jest wywoływane później - zgodnie z cyklem życia aktywności (myślę, że to poprawny termin) , jak wskazuje @ tir38

@Override
public void onResume() {
    super.onResume();
    invalidateOptionsMenu();
}

4
Jeśli używasz actionbarsherlock, zadzwoń do tej metodysupportInvalidateOptionsMenu();
Shan Xeeshi

3
Uważaj, kiedy mówisz „natychmiast”. To naprawdę nie stanie się natychmiast. Kiedy ty invalidateOptionsMenu, zadanie (ponownego) utworzenia menu opcji zostanie dodane do kolejki komunikatów interfejsu użytkownika. Cokolwiek jeszcze jest w kolejce, zostanie uruchomione jako pierwsze.
tir38

21

Dodatek w powyższej odpowiedzi, w przypadku ICS i Honeycomb onCreateOptionsMenu jest wywoływane po onCreate i onPostCreate, natomiast w Gingerbread i wcześniejszych wersjach jest wywoływane po onCreate, ale przed onPostCreate. To jedyna różnica, jaką znalazłem.


3

Z mojego doświadczenia ActionBarActivityz obsługi v7 wynika, że metoda onCreateOptionsMenu()wywołana w setContentView()środku onCreate()pojawia się na 4.1.1.

Ale na 4,4 inna historia onCreateOptionMenu()nazywa po onCreate(). Nie wiem też, że może to nastąpić zaraz potem, może nie. Ale jest faktem później. Nie testowałem na innych wersjach, ale 4.1.1 jest pierwszym, w którym miałem problem z kolejnością inicjalizacji.


Może potrzebujesz użyć supportInvalidateOptionsMenu()?
David d C e Freitas

2

Proponuję utworzyć funkcję zwrotną w swoim fragmencie, aby uniknąć problemów z synchronizacją w onResume () i onCreateOptionsMenu ().

wykonanie następujących czynności bezbłędnie dla mnie:

  1. utwórz i dodaj swój fragment do swojej aktywności
  2. zostaw odniesienie do tego fragmentu w swojej działalności
  3. utwórz publiczną metodę doSomethingWithTheMenu () w swoim fragmencie
  4. wywołaj tę metodę z poziomu swojej aktywności, gdy wywoływana jest metoda onCreateOptionsMenu (menu menu).

przykład:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (this.myFragment != null) {
        this.myFragment.doSomethingWithTheMenu(menu);
    }
    return true;
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.