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

149

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

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

Кристофер Перри
источник

Ответы:

112

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

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

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

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

CommonsWare
источник
Я забыл упомянуть, что я использую библиотеку 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;
}
datayeah
источник