Android: quando o onCreateOptionsMenu é chamado durante o ciclo de vida da atividade?

149

Coloquei alguns pontos de interrupção onCreate(um no início e outro no final do método) e também coloquei um no início de onCreateOptionsMenu. O onCreatemétodo é chamado primeiro e antes de terminar onCreateOptionsMenué chamado.

Estou tentando separar o Fragmentcódigo de navegação no meu aplicativo, então tenho alguns objetos aos quais delegar, onCreateOptionsMenudependendo se o aplicativo está sendo executado no telefone / tablet (estou usando o tamanho da tela para determinar isso, meu arquivo de layout para telas grandes tem uma exibição que eu procuro após o layout ser inflado). O problema que estou tendo é que eu crio esses objetos no onCreate e recebo uma exceção de ponteiro nulo quando faço referência ao objeto onCreateOptionsMenu.

Christopher Perry
fonte

Respostas:

112

O método onCreate é chamado primeiro e, antes de terminar, onCreateOptionsMenu.

Isso será verdade em dispositivos e aplicativos com uma barra de ação oficial no estilo Honeycomb. Se não houver uma barra de ação, onCreateOptionsMenu()não deve ser chamado até o usuário acessar o menu, geralmente pressionando o botão MENU.

(Estou usando o tamanho da tela para determinar isso, meu arquivo de layout para telas grandes tem uma Visualização que verifico após o layout ser inflado)

Esse teste será interrompido muito em breve, quando o Ice Cream Sandwich for enviado. Pelo que sei, os telefones ICS terão barras de ação (embora talvez não sejam barras de sistema).

CommonsWare
fonte
Esqueci de mencionar que estou usando a biblioteca ActionbarSherlock. Sua resposta me lembrou. Essa é provavelmente a razão desse comportamento, pois é um invólucro na biblioteca de compatibilidade, que coloca os itens de menu no "ActionBar".
Christopher Perry
@commonsware - Isso significa em dispositivos e aplicativos que não possuem barra de ação. O menu será exibido mesmo se onCreateOptionsMenu não tiver um item visível?
NinjaCoder
12
no meu caso, chamada onCreateMenu após onResume
Kostya Khuta
1
Sim, tenho o mesmo problema ... Mas meu código está relacionado a um fragmento.
Yoann Hercouet
Comecei a NPEverificar se a entrada nav drawer fragmentestava aberta onCreateOptionsMenu. Eu tive que colocar verificações nulas no onCreateOptionsMenu da atividade, bem como no retorno de chamada que o fragmento estava usando no onCreateOptionsMenu. Realmente estranho, porque só acontecia em algumas telas, mas consistentemente nessas.
theblang
54

No meu caso no Android 2.3 e com a FragmentActivitypartir da biblioteca de suporte da v4, a ordem dos métodos do ciclo de vida é a seguinte:

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:
Roman Nazarevych
fonte
27

Descobri que em onResume () eu chamo

invalidateOptionsMenu();

depois, onCreateOptionsMenu (menu Menu) é chamado posteriormente - conforme o ciclo de vida da atividade (acho que esse é o termo correto aqui) , conforme indicado por @ tir38

@Override
public void onResume() {
    super.onResume();
    invalidateOptionsMenu();
}
Gene Bo
fonte
4
Se u estão usando ActionBarSherlock em seguida, chamar esse métodosupportInvalidateOptionsMenu();
Shan Xeeshi
3
Tenha cuidado ao dizer "imediatamente". Isso realmente não vai acontecer imediatamente. Quando você invalidateOptionsMenu, um trabalho para (re) criar o menu de opções será adicionado à fila de mensagens da interface do usuário. O que quer que esteja na fila será executado primeiro.
tir38
21

Além da resposta acima, no caso do ICS e do Honeycomb, onCreateOptionsMenu é chamado após onCreate e onPostCreate, enquanto no Gingerbread e em versões anteriores, é chamado após onCreate, mas antes em onPostCreate. Essa é a única diferença que encontrei.

Pawan Maheshwari
fonte
3

Na minha experiência ActionBarActivitycom o suporte v7 onCreateOptionsMenu()chamado setContentView()método no meio onCreate()dele, é apresentado em 4.1.1.

Mas no 4.4 outra história foi onCreateOptionMenu()chamada depois onCreate(). Também não sei se pode ser imediatamente depois, talvez não. Mas é fato depois. Não testei em outras versões, mas o 4.1.1 é o primeiro onde tive um problema com a ordem de inicialização.

Yevgen Kulik
fonte
Talvez você precise usar supportInvalidateOptionsMenu()?
David d C e Freitas
2

Sugiro criar uma função de retorno de chamada em seu fragmento para evitar problemas de temporização com onResume () e onCreateOptionsMenu ().

fazendo o seguinte funciona perfeitamente para mim:

  1. crie e adicione seu fragmento à sua atividade
  2. deixe uma referência desse fragmento em sua atividade
  3. crie um método público doSomethingWithTheMenu () em seu fragmento
  4. chame esse método de dentro da sua atividade quando for chamado onCreateOptionsMenu (menu Menu).

exemplo:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (this.myFragment != null) {
        this.myFragment.doSomethingWithTheMenu(menu);
    }
    return true;
}
datayeah
fonte