简体   繁体   中英

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 (ie 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)

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM