Pourquoi onAttach est-il appelé avant onCreate?

Dans le cycle de vie d’un fragment, la méthode onAttach () est appelée avant la méthode onCreate (). Je ne peux pas m’envelopper avec ça. Pourquoi voudriez-vous attacher un fragment d’abord?

TL; DR :

Afin de ne pas casser la cohérence de la conception entre les différents composants de l’interface utilisateur dans Android, la méthode onCreate() aura des fonctionnalités similaires pour tous.

Lors de la liaison de conteneurs à des contenus tels que Window to Activity et Activity to Fragment, une vérification préliminaire doit être effectuée pour déterminer l’état du conteneur. Et cela explique l’utilisation et la position de onAttach() dans le cycle de vie des fragments.

Trop court, besoin de plus de temps:

La réponse est dans le code archétype lui-même,

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

Un autre exemple serait la bibliothèque ActionBarSherlock de Jake Wharton.

Pourquoi voudriez-vous utiliser une méthode comme onCreate() qui a le même objective dans une activité , un service .

onCreate() est conçu pour traiter les problèmes onCreate() création de ce contexte particulier. Cela n’a aucun sens si onCreate() est utilisé pour vérifier l’état de son conteneur.

La seconde raison pour laquelle je peux déterminer est qu’un fragment est conçu pour être indépendant de l’activité. onAttach() fournit une interface pour déterminer l’état / le type / (autre détail important pour le fragment) de l’activité contenant fragmenter avant d’initialiser un fragment.

EDIT :

Une activité existe indépendamment et a donc un cycle de vie autonome.

pour un fragment:

  1. Les composants de cycle de vie indépendants (identiques à tous les autres composants):

    • onCreate ()
    • onStart ()
    • pour résumer()
    • onPause ()
    • onStop ()
    • onDestroy ()
  2. Les composants basés sur l’interaction:

    • onAttache ()
    • onCreateView ()
    • onActivityCreated ()
    • onDestroyView ()
    • onDetach ()

à partir de la documentation :

Le stream de vie d’un fragment, affecté par son activité hôte (…), chaque état successif de l’activité détermine les méthodes de rappel qu’un fragment peut recevoir. Par exemple, lorsque l’activité a reçu son rappel onCreate (), un fragment de l’activité ne reçoit plus que le rappel onActivityCreated ().

Une fois que l’activité a atteint l’état de reprise, vous pouvez librement append et supprimer des fragments à l’activité. Ainsi, le cycle de vie d’un fragment ne peut être modifié que lorsque l’activité est dans l’état de reprise.

Toutefois, lorsque l’activité quitte l’état de reprise, le fragment est à nouveau poussé dans son cycle de vie par l’activité.

répondre à une autre question qui a été soulevée dans les commentaires:

Attention : Si vous avez besoin d’un object Context dans votre fragment, vous pouvez appeler getActivity (). Toutefois, veillez à appeler getActivity () uniquement lorsque le fragment est associé à une activité. Lorsque le fragment n’est pas encore connecté ou a été déconnecté à la fin de son cycle de vie, getActivity () renvoie null.

La philosophie de conception stipule qu’un fragment est conçu pour être réutilisé. Un fragment (par conception) pourrait (et devrait) être utilisé pour plusieurs activités.

onCreate par définition est responsable de créer un fragment. Prenons le cas de l’orientation, votre fragment pourrait être: – utilisant différentes dispositions dans différentes orientations. – applicable uniquement en mode portrait et non en mode paysage – à utiliser uniquement sur les tables et les téléphones portables.

Toutes ces situations nécessiteraient une vérification avant que le fragment ne soit initialisé à partir de la perspective android ( onCreate() ) et la vue gonflée ( onCreateView() ).

Considérez également la situation d’un fragment sans tête . onAttach() vous fournit l’interface requirejse pour les vérifications préliminaires.

Parce que onAttach() affecte l’activité d’hébergement au Fragment . S’il avait été appelé après onCreate() il n’y aurait pas de contexte pour votre fragment ( getActivity() renverrait null ) et vous ne pourriez rien faire de la méthode onCreate() sans ce contexte.

Une autre raison est que le cycle de vie de Fragment est similaire au cycle de vie de l’activité. Dans Activity.onAttach() activité est attachée à son parent (une fenêtre). De même, dans Fragment.onAttach() fragment est attaché à son parent (une activité) avant toute autre initialisation.

Ceci est lié aux fragments conservés. Suite Fragment setRetainInstance(boolean retain) documentation:

S’il est défini, le cycle de vie des fragments sera légèrement différent lors de la recréation d’une activité:

  • onDestroy () ne sera pas appelé (mais onDetach () le sera toujours, car le fragment est détaché de son activité en cours).
  • onCreate (Bundle) ne sera pas appelé car le fragment n’est pas recréé.
  • onAttach (Activity) et onActivityCreated (Bundle) seront toujours appelés.

Regardez le code source (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 } ... } 

Exemple

Cas 1: fragment non retenu ou setRetainInstanceState (false)

L'application est démarrée. Le fragment est ajouté dynamicment à l'aide de FragmentManager ou gonflé à partir de XML via setContentView() .

onAttach() appelé après l' activité super.onCreate() call - L'activité est déjà initialisée.

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

La configuration a changé Activité recrée des fragments à partir de l’état enregistré, des fragments sont ajoutés / attachés depuis l’ super.onCreate() Activity super.onCreate() :

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

Cas 2: setRetainsInstanceState (true)

L'application est démarrée. Le fragment est ajouté dynamicment à l'aide de FragmentManager ou gonflé à partir de XML via setContentView() . Comme ci-dessus:

onAttach() appelé après l' activité super.onCreate() call - L'activité est déjà initialisée.

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

La configuration a changé

Fragment onCreate() non appelé, mais onAttach() toujours appelé - vous devez savoir que l'activité d'hébergement a changé. Mais le fragment est déjà créé, donc onCreate() n’a pas onCreate() appelé.

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

Deux points du développeur Android Site indique pourquoi onAttach() est appelé avant onCreate() en cas de cycle de vie de fragment.

  1. Un fragment doit toujours être incorporé dans une activité. Maintenant, cela signifie que Fragment EXIST, il doit y avoir une activité “vivante”.
    En outre, lorsque vous ajoutez un fragment dans la présentation de votre activité, il se trouve dans un ViewGroup à l’intérieur de la hiérarchie de vues de l’activité.

Donc, Fragment doit FIRST “s’attacher” lui-même à l’activité pour définir sa propre disposition de vue

  1. onCreate est appelé à créer un fragment.

Il est évident que vous ne créerez quelque chose que lorsque sa condition préalable à la création est en place (et que la condition préalable est Un fragment doit toujours être incorporé dans une activité et doit être associé à son activité).