Android: когда вызывается onCreateOptionsMenu в течение жизненного цикла Activity?


149

Я установил пару точек останова onCreate(одну в начале и одну в конце метода), а также одну в начале onCreateOptionsMenu. onCreateМетод вызывается первым, и до его завершения onCreateOptionsMenuназывается.

Я пытаюсь разделить Fragmentкод навигации в своем приложении, поэтому у меня есть несколько объектов, которым я делегирую onCreateOptionsMenuв зависимости от того, запущено ли приложение на телефоне / планшете (для определения этого я использую размер экрана, мой файл макета для на больших экранах есть вид, который я проверяю после раздувания макета). Проблема в том, что я создаю эти объекты в onCreate и получаю исключение нулевого указателя, когда ссылаюсь на объект в onCreateOptionsMenu.

Ответы:


112

Сначала вызывается метод onCreate, а до его завершения вызывается onCreateOptionsMenu.

Это будет справедливо для устройств и приложений с официальной панелью действий в стиле Honeycomb. Если панель действий отсутствует, onCreateOptionsMenu()ее не следует вызывать до тех пор, пока пользователь не вызовет меню, обычно нажатием кнопки MENU.

(Я использую размер экрана, чтобы определить это, мой файл макета для больших экранов имеет проверку, которую я проверяю после того, как макет накачан)

Это испытание скоро пройдет, как только выйдет Ice Cream Sandwich. Насколько я могу судить, телефоны ICS будут иметь панели действий (хотя, возможно, и не системные).


Я забыл упомянуть, что я использую библиотеку ActionbarSherlock. Ваш ответ напомнил мне. Вероятно, в этом причина такого поведения, поскольку это оболочка библиотеки совместимости, которая помещает пункты меню в «ActionBar».
Кристофер Перри

@commonsware - это означает, что на устройствах и в приложениях отсутствует панель действий. Меню будет отображаться, даже если в onCreateOptionsMenu нет видимого элемента?
NinjaCoder

12
в моем случае вызов onCreateMenu после onResume
Костя Хута

1
Да, у меня та же проблема ... Но мой код связан с фрагментом.
Йоанн Херкуэ

Я начал иметь NPEпри проверке, nav drawer fragmentбыл ли открыт в onCreateOptionsMenu. Мне пришлось поставить нулевые проверки как в onCreateOptionsMenu действия, так и в обратном вызове, который фрагмент использовал в своем onCreateOptionsMenu. Действительно странно, потому что это происходило только на нескольких экранах, но последовательно на тех.
theblang

54

В моем случае на Android 2.3 и с FragmentActivityбиблиотекой v4-support порядок вызова методов жизненного цикла следующий:

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

Я нашел, если в onResume () я звоню

invalidateOptionsMenu();

затем вызывается onCreateOptionsMenu (меню меню) - в соответствии с жизненным циклом действия (я думаю, что это правильный термин здесь) , как указано @ tir38

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

4
Если вы используете actionbarsherlock, тогда назовите этот методsupportInvalidateOptionsMenu();
Shan Xeeshi

3
Будьте осторожны, когда говорите «немедленно». Это не произойдет сразу. Когда вы invalidateOptionsMenu, задание (пере) создать меню параметров будет добавлено в очередь сообщений пользовательского интерфейса. Все, что находится в очереди, будет запущено первым.
tir38

21

Добавление в ответе выше, в случае ICS и Honeycomb onCreateOptionsMenu вызывается после onCreate и onPostCreate, тогда как в Gingerbread и более ранних версиях он вызывается после onCreate, но до onPostCreate. Это единственная разница, которую я нашел.


3

По моему опыту ActionBarActivityиз поддержки v7 onCreateOptionsMenu()вызванный setContentView()метод в середине onCreate()этого появляется на 4.1.1.

Но на 4.4 другая история onCreateOptionMenu()называется после onCreate(). Кроме того, я не знаю, это может быть сразу после, а может и нет. Но это факт после. Я не тестировал другие версии, но 4.1.1 - первая, где у меня были проблемы с порядком инициализации.


Возможно, вам нужно использовать supportInvalidateOptionsMenu()?
Дэвид д'Э Фрейтас

2

Я предлагаю создать функцию обратного вызова в вашем фрагменте, чтобы избежать проблем с синхронизацией с onResume () и onCreateOptionsMenu ().

выполнение следующих работ для меня безупречно:

  1. создать и добавить свой фрагмент в вашу деятельность
  2. оставить ссылку на этот фрагмент в вашей деятельности
  3. создайте публичный метод doSomethingWithTheMenu () в вашем фрагменте
  4. вызывайте этот метод из своей деятельности, когда вызывается onCreateOptionsMenu (меню Menu).

пример:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (this.myFragment != null) {
        this.myFragment.doSomethingWithTheMenu(menu);
    }
    return true;
}
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.