Android:在Activity生命周期中何时调用onCreateOptionsMenu?


149

我在其中加入了两个断点onCreate(在方法的开始处有一个断点,在方法的末尾有一个断点),在的开始处也有一个断点onCreateOptionsMenu。该onCreate方法首先被调用,然后在完成之前onCreateOptionsMenu被调用。

我试图Fragment在应用程序中分离导航代码,所以我有几个对象要委托onCreateOptionsMenu给我,具体取决于应用程序是否在手机/平板电脑上运行(我正在使用屏幕尺寸来确定此布局,我的布局文件用于大屏幕有一个视图,在布局放大后我会检查该视图)。我遇到的问题是,我在onCreate中创建了这些对象,当我在中引用对象时遇到了空指针异常onCreateOptionsMenu

Answers:


112

首先调用onCreate方法,然后再调用onCreateOptionsMenu。

在具有官方Honeycomb风格操作栏的设备和应用上,这将是正确的。如果没有操作栏,onCreateOptionsMenu()则在用户调出菜单之前,通常不按菜单按钮,否则不应调用它。

(我正在使用屏幕尺寸来确定这一点,大屏幕的布局文件具有放大后的视图,我会对其进行检查)

一旦Ice Cream Sandwich出厂,该测试将很快终止。据我所知,ICS手机将具有操作栏(尽管可能没有系统栏)。


我忘了提到我正在使用ActionbarSherlock库。你的回答使我想起了。这可能是此行为的原因,因为它是兼容性库的包装,将菜单项放在“ ActionBar”中。
Christopher Perry

@commonsware-这意味着在没有操作栏的设备和应用上。即使onCreateOptionsMenu没有可见的菜单,菜单也会显示出来?
NinjaCoder 2013年

12
在我的情况下onResume之后的onCreateMenu调用
Kostya Khuta 2014年

1
是的,我有同样的问题...但是我的代码与Fragment有关。
Yoann Hercouet 2014年

我开始NPE检查时是否nav drawer fragment打开onCreateOptionsMenu。我必须在活动的onCreateOptionsMenu以及该片段在其onCreateOptionsMenu中使用的回调中都进行空检查。真的很奇怪,因为它只在几个屏幕上发生,但始终在那些屏幕上发生。
theblang 2014年

54

就我而言,在Android 2.3上以及FragmentActivity从v4支持库中开始,生命周期方法的调用顺序如下:

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(Menu menu)随后被调用-按照活动生命周期 (我认为这是正确的术语),如@ tir38所示

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

4
如果妳使用actionbarsherlock然后调用该方法supportInvalidateOptionsMenu();
山Xeeshi

3
立即说“当心”。它不会真正立即发生。当您invalidateOptionsMenu执行(重新)创建选项菜单的工作时,将添加到UI的消息队列中。队列中的其他任何内容都将首先运行。
tir38 '16

21

除上述答案外,如果是ICS和Honeycomb,则在onCreate和onPostCreate之后调用onCreateOptionsMenu,而在Gingerbread和更早版本中,在onCreate之后但在onPostCreate之前调用onCreateOptionsMenu。那就是我发现的唯一区别。


3

根据我的经验ActionBarActivity,从支持V7 onCreateOptionsMenu()调用setContentView()方法的中间onCreate()是出现在4.1.1。

但是在4.4上还有一个故事onCreateOptionMenu()onCreate()。我也不知道可能是紧接之后,也许不是。但是是事实。我没有在其他版本上进行测试,但是4.1.1首先是我在初始化顺序方面遇到麻烦的地方。


也许您需要使用supportInvalidateOptionsMenu()
David d C e Freitas

2

我建议在您的片段中创建一个回调函数,以避免onResume()和onCreateOptionsMenu()的计时问题。

对我而言,完成以下工作无懈可击:

  1. 创建片段并将其添加到活动中
  2. 在您的活动中留下这个片段的参考
  3. 在您的片段中创建一个公共方法doSomethingWithTheMenu()
  4. 在调用onCreateOptionsMenu(Menu menu)时从您的活动中调用此方法。

例:

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    if (this.myFragment != null) {
        this.myFragment.doSomethingWithTheMenu(menu);
    }
    return true;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.