为什么在onCreate之前调用onAttach?

在片段的生命周期中,onAttach()方法在onCreate()方法之前被调用。 我无法解决这个问题。 为什么要先附加一个片段?

Simon asked 2020-02-13T21:37:19Z
4个解决方案
36 votes

TL; DR:

为了不破坏android中不同UI组件之间的设计一致性,onAttach()方法将在所有组件之间具有相似的功能。

当将容器链接到诸如窗口的窗口链接到活动和将活动的链接链接到片段之类的内容时,需要进行初步检查以确定容器的状态。这就解释了onAttach()在片段生命周期中的使用和位置。

太短;需要更长:

答案在于原型代码本身,

@Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnFragmentInteractionListener");
        }
    }

另一个示例将在Jake Wharton的ActionBarSherlock库中。

您为什么要使用像onAttach()这样的方法,在活动,服务中具有相同的目的。

onAttach()旨在处理与特定上下文创建有关的问题,如果使用onCreateView()检查其容器的状态则没有意义。

我可以确定的第二个原因是片段被设计为与活动无关 您初始化一个片段。

编辑:

活动是独立存在的,因此具有自我维持的生命周期。

对于一个片段:

  1. 独立的生命周期组件(与任何其他组件相同):

    • onCreate()
    • onStart()
    • onResume()
    • onPause()
    • onStop()
    • onDestroy()
  2. 基于交互的组件:

    • onAttach()
    • onCreateView()
    • onActivityCreated()
    • onDestroyView()
    • onDetach()

从文档中:

片段的生命周期流,受其宿主影响   活动,(...)活动的每个连续状态确定   片段可能接收的回调方法。 例如,当   活动已收到其onCreate()回调,该回调是   活动收到的内容最多不过是onActivityCreated()回调。

活动达到恢复状态后,您可以自由添加和   删除活动的碎片。 因此,只有在活动进行中   恢复状态可以改变片段的生命周期   独立地。

但是,当活动离开恢复状态时,该片段   活动再次将其推向生命周期。

回答评论中出现的另一个问题:

警告:如果您在Fragment中需要一个Context对象,则可以调用getActivity()。 但是,只有在将片段附加到活动时,才应小心调用getActivity()。 如果片段尚未附加或在其生命周期结束时分离,则getActivity()将返回null。

设计理念指出,片段是为重用而设计的。 一个片段(通过设计)可以(并且应该)用于多个活动。

根据定义,onAttach()负责创建片段。考虑定向的情况,您的片段可能是:-在不同的方向上使用不同的布局。-仅适用于纵向,不适用于横向-仅在桌子和手机上使用。

从android透视图初始化片段之前,所有这些情况都需要检查(onAttach()),然后视图膨胀(onCreateView())。

还要考虑无头碎片的情况。onAttach()提供了初步检查所需的接口。

Droidekas answered 2020-02-13T21:39:59Z
13 votes

因为Activity.onAttach()将托管活动分配给Fragment.onAttach()。如果在onCreate()之后调用了托管活动,则您的片段将没有上下文(getActivity()将返回null),如果没有该上下文,您将无法在onCreate()方法中执行任何操作。

另一个合适的原因是,Fragment的生命周期类似于Activity的生命周期。 在Activity.onAttach()中,活动被附加到其父项(窗口)。 同样,在Fragment.onAttach()中,片段会附加到其父对象(活动),然后再进行其他初始化。

sergej shafarenka answered 2020-02-13T21:40:25Z
9 votes

这与保留的片段有关。 遵循片段onCreate()文档:

如果设置,则重新创建活动时,片段生命周期将略有不同:

  • onDestroy()将不会被调用(但onDetach()仍会被调用,因为该片段正在从其当前活动中分离出来)。
  • 由于不会重新创建片段,因此不会调用onCreate(Bundle)。
  • onAttach(Activity)和onActivityCreated(Bundle)仍将被调用。

看一下源代码(android.support.v4.app.FragmentManager,v21):

void moveToState(Fragment f, 
                 int newState, 
                 int transit, 
                 int transitionStyle,
                 boolean keepActive) {
    ...
    f.onAttach(mActivity);
    if (!f.mCalled) {
        throw new SuperNotCalledException("Fragment " + f
                + " did not call through to super.onAttach()");
    }
    if (f.mParentFragment == null) {
        mActivity.onAttachFragment(f);
    }

    if (!f.mRetaining) {
        f.performCreate(f.mSavedFragmentState); // <- Here onCreate() will be called
    }
    ...
}

情况1:未保留的片段或setRetainInstanceState(false)

应用程序启动。 可以使用FragmentManager动态添加片段,也可以通过onCreate()从XML扩展片段。

在活动onAttach()调用后调用了onCreate()-活动已初始化。

MainActivity﹕ call super.onCreate() before
MainActivity﹕ super.onCreate() returned
MainFragment﹕ onAttach() getActivity=com.example.MainActivity@1be4f2dd
MainFragment﹕ onCreate() getActivity=com.example.MainActivity@1be4f2dd

配置已更改。 活动从保存的状态重新创建片段,从活动onCreate()调用中添加/附加片段:

MainActivity﹕ call super.onCreate() before
MainFragment﹕ onAttach() getActivity=com.example.MainActivity@2443d905
MainFragment﹕ onCreate() getActivity=com.example.MainActivity@2443d905
MainActivity﹕ super.onCreate() returned

情况2:setRetainsInstanceState(true)

应用程序启动。 使用FragmentManager动态添加片段,或通过onCreate()从XML扩展片段。与上面相同:

在活动onAttach()调用后调用了onCreate()-活动已初始化。

MainActivity﹕ call super.onCreate() before
MainActivity﹕ super.onCreate() returned
MainFragment﹕ onAttach() getActivity=com.example.MainActivity@3d54a168
MainFragment﹕ onCreate() getActivity=com.example.MainActivity@3d54a168

配置已更改。

片段onCreate()未调用,但onAttach()仍被调用-您需要知道,托管活动已更改。 但是仍然已经创建了片段,因此没有调用onCreate()

MainActivity﹕ call super.onCreate() before
MainFragment﹕ onAttach() getActivity=com.example.MainActivity@d7b283e
MainActivity﹕ super.onCreate() returned
jskierbi answered 2020-02-13T21:41:51Z
2 votes

来自Android开发人员网站的两点暗示了为什么在“片段生命周期”的情况下,在onCreate()之前调用onCreate

  1. 片段必须始终嵌入活动中。 现在,这意味着要存在Fragment,必须有一个“活着的”活动。
    同样,当您将片段添加为活动布局的一部分时,它位于活动视图层次结构内的ViewGroup中。

因此,Fragment必须首先将自身“附加”到活动以定义其自己的视图布局

  1. onCreateis被要求进行片段的初始创建。

显然,只有在其创建的前提条件到位时,您才会创建某些东西(前提条件是片段必须始终嵌入活动中,并且必须附加到其活动中)

AADProgramming answered 2020-02-13T21:42:34Z
translate from https://stackoverflow.com:/questions/29677812/why-is-onattach-called-before-oncreate