从Fragment(ActionBarCompat)内部调用getSupportActionBar()时出现NullPointerException

时间:2014-06-10 22:44:02

标签: java android android-actionbar android-support-library android-actionbar-compat

我刚从ActionBarSherlock切换到ActionBarCompat,一切运行良好,直到遇到这个小错误。我有一个扩展ActionBarActivity的基本活动,并有3个与之关联的片段。在其中一个Fragments onAttach方法中,我尝试执行此代码:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);
    final ActionBar actionBar = ((ActionBarActivity)activity).getSupportActionBar();

    actionBar.setHomeButtonEnabled(true);
    actionBar.setDisplayHomeAsUpEnabled(true);
    actionBar.setDisplayShowTitleEnabled(false);
    actionBar.setTitle("");
}

在我尝试更改屏幕方向之前,它工作正常。然后我为这行代码获得NullPointerExceptionactionBar.setHomeButtonEnabled(true);

我该如何解决这个问题?

修改

以下是整个错误日志:

06-10 18:53:31.440: E/AndroidRuntime(18586): FATAL EXCEPTION: main
06-10 18:53:31.440: E/AndroidRuntime(18586): Process: com.packagename.appname, PID: 18586
06-10 18:53:31.440: E/AndroidRuntime(18586): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.packagename.appname/com.packagename.appname.activities.NewActivity}: java.lang.NullPointerException
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2328)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2386)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3947)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.app.ActivityThread.access$1000(ActivityThread.java:169)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1283)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.os.Handler.dispatchMessage(Handler.java:102)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.os.Looper.loop(Looper.java:136)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.app.ActivityThread.main(ActivityThread.java:5476)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at java.lang.reflect.Method.invokeNative(Native Method)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at java.lang.reflect.Method.invoke(Method.java:515)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1268)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1084)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at dalvik.system.NativeStart.main(Native Method)
06-10 18:53:31.440: E/AndroidRuntime(18586): Caused by: java.lang.NullPointerException
06-10 18:53:31.440: E/AndroidRuntime(18586):    at com.packagename.appname.fragments.NewFragment.onAttach(NewFragment.java:144)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:883)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1104)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.support.v4.app.FragmentManagerImpl.moveToState(FragmentManager.java:1086)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.support.v4.app.FragmentManagerImpl.dispatchCreate(FragmentManager.java:1879)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:215)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.support.v7.app.ActionBarActivity.onCreate(ActionBarActivity.java:97)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at com.packagename.appname.activities.NewActivity.onCreate(NewActivity.java:73)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.app.Activity.performCreate(Activity.java:5451)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1093)
06-10 18:53:31.440: E/AndroidRuntime(18586):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2292)
06-10 18:53:31.440: E/AndroidRuntime(18586):    ... 12 more

仅供参考:NewFragment第144行是:actionBar.setHomeButtonEnabled

1 个答案:

答案 0 :(得分:8)

onAttach()可能太早了。在旋转之后重新创建活动时,它甚至是在完全创建活动之前调用的第一个方法之一(即其onCreate()尚未完成)。因此,ActionBar尚未准备就绪并不奇怪。

检查文档中的relationship between Activity and Fragment's lifecycles

简而言之:将此代码移至onActivityCreated()onStart()

进一步说明

检查ActionBarActivity的源代码:

@Override
protected void onCreate(Bundle savedInstanceState) {
    mImpl = ActionBarActivityDelegate.createDelegate(this);
    super.onCreate(savedInstanceState);
    mImpl.onCreate(savedInstanceState);
}
  • super.onCreate()FragmentActivity.onCreate(),它会在轮换后恢复之前的所有片段。
  • mImpl.onCreate(savedInstanceState)ActionBarActivityDelegate.onCreate(),它从窗口样式中读取mHasActionBar变量。
  • mHasActionBar为真之前,getSupportActionBar()将始终返回null。