在Activity的onCreate完成之前,是否可以调用片段onAttach?

时间:2016-11-06 01:03:49

标签: android android-fragments

我正在经历一次非常罕见的(几千次会话中的一次)崩溃,我正试图追查。我有一个活动,在其创建覆盖期间,它会创建一些片段,但不会显示或附加任何片段:

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

在这段代码中,我还创建了一个" MainPresenter"它来自一个包含我们所有业务逻辑的库。演示者使用片段的onAttach方法:

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

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

问题是,我很少在onAttach中获得null ptr异常。是否有可能在某些罕见的情况下片段的onAttach正在活动之前执行。 onCreate已经完成(即mainPresenter为空)?

更新

以下是导致崩溃的callstack的一部分,以防它有用:

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)

2 个答案:

答案 0 :(得分:2)

是。请参阅https://developer.android.com/reference/android/app/Fragment.html#onCreate(android.os.Bundle)处的文档。 Fragment.onAttach发生在Fragment.onCreate之前,并且如果onCreate的文档说该活动仍然处于在此生命周期方法中创建的过程中,那么这意味着它肯定可以在onAttach中构建,这在onCreate之前发生。

至于您的具体情况,如果这是您活动的整个onCreate,那么这些片段根本不会挂钩到应用程序中;它们尚未通过片段管理器添加。它们仅被实例化,并且还没有Android生命周期调用。我假设有一些更复杂的事情发生了,并且在配置发生变化之后会重新添加片段,或者当你遇到崩溃时会重新添加片段。

答案 1 :(得分:0)

您可能希望将Activity#onCreate声明更改为:

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

这是因为 super.onCreate(savedInstanceState)触发了活动片段的(重新)附加,并且系统通过调用 Fragment.onAttach()来实现。 / p>

但是,在您的情况下,mainPresenter应该已经被实例化/初始化,因为它在Fragment.onAttach中是必需的,但是还不是,因为它在 super.onCreate(savedInstanceState)以下当前正在执行。

相关问题