Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NullPointerException when calling getSupportActionBar() from inside of Fragment (ActionBarCompat)

I just switched from ActionBarSherlock to ActionBarCompat and everything was working well until I ran into this small error. I have a base activity that extends ActionBarActivity and has 3 fragments associated with it. In one of the Fragments onAttach method, I try executing this code:

@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("");
}

It works fine until I try to change my screen orientation. Then I get a NullPointerException for this line of code: actionBar.setHomeButtonEnabled(true);.

How can I fix this?

Edit:

Here is the entire error log:

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

FYI: NewFragment line 144 is: actionBar.setHomeButtonEnabled.

like image 877
lschlessinger Avatar asked Jun 10 '14 22:06

lschlessinger


1 Answers

onAttach() may be far too soon. When the activity is recreated after a rotation, it is one of the first methods called, even before the Activity is fully created (i.e. its onCreate() hasn't finished yet). So it's not surprising that the ActionBar isn't ready.

Check the relationship between Activity and Fragment's lifecycles in the documentation.

In short: move this code into onActivityCreated() or onStart().

Further explanation

Check the source code for ActionBarActivity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    mImpl = ActionBarActivityDelegate.createDelegate(this);
    super.onCreate(savedInstanceState);
    mImpl.onCreate(savedInstanceState);
}
  • super.onCreate() is FragmentActivity.onCreate(), which restores any previous fragments after a rotation.
  • mImpl.onCreate(savedInstanceState) is ActionBarActivityDelegate.onCreate(), which reads the mHasActionBar variable from the window style.
  • Before mHasActionBar is true, getSupportActionBar() will always return null.
like image 81
matiash Avatar answered Oct 14 '22 17:10

matiash