繁体   English   中英

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

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

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

@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 异常。 在某些极少数情况下,是否有可能在活动的 onCreate 完成之前执行片段的 onAttach(即 mainPresenter 为空)?

更新

这是导致崩溃的调用堆栈的一部分,以防万一:

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)

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

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

您可能希望将 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() 来执行此操作。

但是,在您的情况下,mainPresenter 应该已经实例化/初始化,因为它在 Fragment.onAttach 中是需要的,但事实并非如此[还],因为它位于当前正在执行的super.onCreate(savedInstanceState)之下。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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