user3690202
user3690202

Reputation: 4075

Can a fragment's onAttach be called before the Activity's onCreate has finished?

I am experiencing a very rare (1 in a few thousand sessions) crash which I am trying to track down. I have an Activity which, during it's onCreate override, it creates some fragments but doesn't show or attach any of them:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
    setContentView(R.layout.activity_main);

    mainMenuFragment = new MainMenuFragment();
    locationFragment = new LocationFragment();

    mainPresenter = new MainPresenter(this);
}

In this code I also create a "MainPresenter" which comes from a library which contains all our business logic. The presenter is used from the onAttach method of the fragments:

@Override
public void onAttach(Activity activity) {
    super.onAttach(activity);

    MainActivity mainActivity = (MainActivity) activity;
    mainPresenter = mainActivity.getMainPresenter();
    mainPresenter.refreshUI();
}

The issue is, that very rarely I am getting a null ptr exception in the onAttach. Is it possible that in some rare cases the fragment's onAttach is being executed before the Activities' onCreate has finished (i.e. mainPresenter is null)?

Update

Here is part of the callstack leading up to the crash, in case it is helpful:

android.app.ActivityThread.performLaunchActivity (ActivityThread.java:3253)
android.app.ActivityThread.handleLaunchActivity (ActivityThread.java:3349)
android.app.ActivityThread.handleRelaunchActivity (ActivityThread.java:5383)
android.app.ActivityThread.access$1200 (ActivityThread.java:221)
android.app.ActivityThread$H.handleMessage (ActivityThread.java:1800)
android.os.Handler.dispatchMessage (Handler.java:102)
android.os.Looper.loop (Looper.java:158)
android.app.ActivityThread.main (ActivityThread.java:7225)
java.lang.reflect.Method.invoke (Method.java)
com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run (ZygoteInit.java:1230)
com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1120)

Upvotes: 4

Views: 2415

Answers (2)

Akintunde
Akintunde

Reputation: 1

You may want to change your Activity#onCreate declaration to:

@Override
protected void onCreate(Bundle savedInstanceState) {
    mainMenuFragment = new MainMenuFragment();

    locationFragment = new LocationFragment();

    mainPresenter = new MainPresenter(this);

    super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);

    getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

   setContentView(R.layout.activity_main);
} 

This is because super.onCreate(savedInstanceState) triggers the (re)attachment of the activity fragments and the system does this by calling Fragment.onAttach().

However, in your case, mainPresenter ought to have been instantiated/initialized because it's needed in Fragment.onAttach, but it isn't so [yet] because it's below super.onCreate(savedInstanceState) which is currently in execution.

Upvotes: 0

Chip Thien
Chip Thien

Reputation: 81

Yes. See the documentation at https://developer.android.com/reference/android/app/Fragment.html#onCreate(android.os.Bundle). Fragment.onAttach happens before Fragment.onCreate and if the documentation for onCreate says that the activity can still be in the process of being created during this lifecycle method, then that means that it definitely can be under construction in onAttach, which happens before onCreate.

As to your specific scenario, if that is your entire onCreate of the activity, then those fragments are not hooked into the application at all; they have not been added via the fragment manager. They are only instantiated and cannot have Android lifecycle calls yet. I assume that there is something more complex going on and that fragments are being re-added after a configuration change or something when you get the crash.

Upvotes: 3

Related Questions