После поворота фрагмент onCreate() вызывается до onCreate() FragmentActivity.

Я использую FragmentActivity и фрагменты.

Когда приложение запускается:

FragmentActivity onCreate() <------
FragmentActivity onStart()
FragmentActivity onResume()
Fragment onAttach()
Fragment onCreate() <------
Fragment onCreateView()
Fragment onActivityCreated()
Fragment onStart()
Fragment onResume()

Все в порядке, FragmentActivity onCreate() вызывается перед Fragment onCreate(). И когда я поворачиваюсь:

Fragment onPause()
FragmentActivity onPause()
Fragment onStop()
FragmentActivity onStop()
Fragment onDestroyView()
Fragment onDestroy()
Fragment onDetach()
FragmentActivity onDestroy()
---
Fragment onAttach()
Fragment onCreate() <----------
FragmentActivity onCreate() <---------
Fragment onCreateView()
Fragment onActivityCreated()
Fragment onStart()
FragmentActivity onStart()
FragmentActivity onResume()
Fragment onResume()

Фрагмент onCreate() вызывается перед FragmentActivity onCreate(). Почему это непоследовательно?

В FragmentActivity onCreate() я генерирую некоторые данные, которые получает Fragment onCreate(). Из-за этого странного поведения мне пришлось переместить свой код из Fragment onCreate() в Fragment onCreateView(), чтобы убедиться, что мои данные были сгенерированы раньше.

Я использую FragmentStatePagerAdapter для хранения фрагментов, может быть, в этом причина?


comment
Итак, каково ваше решение?   -  person levi    schedule 28.08.2014
comment
@levi Заполните свои представления данными в методе фрагмента onActivityCreated(). Или переосмыслите свою архитектуру, в большинстве случаев вам не нужно получать данные из активности хоста. И используйте загрузчики, если у вас есть ListView/RecyclerView с динамическими данными. Это было мое окончательное решение, потому что у меня был список в каждом фрагменте. Вы также можете использовать библиотеку шины сообщений (EventBus, Otto, ...), чтобы иметь еще более чистую архитектуру.   -  person AppiDevo    schedule 15.03.2017


Ответы (2)


Вы не должны рассчитывать на действительное действие, пока onActivityCreated() вызов в жизненном цикле фрагмента.

Вызывается при создании действия фрагмента и создании экземпляра иерархии представлений этого фрагмента. Его можно использовать для окончательной инициализации после того, как эти части будут установлены, например, для получения представлений или восстановления состояния.

Точных причин, по которым порядок перестроения нелинейный, я вам сказать не могу. Вероятно, более эффективно позволить каждому компоненту перезапускаться в своем собственном темпе, чем навязывать жесткий порядок. Например, я предпочитаю, чтобы мой LoaderManager запускался как можно раньше, и мы позаботимся о макете его содержимого позже.

(Я люблю хорошую диаграмму.)

введите здесь описание изображения

person Sam    schedule 30.12.2012
comment
Безопасно инициировать Лодеры в onActivityCreated() из-за ошибки, а не раньше. code.google.com/p/android/issues/detail?id= 183783 - person AppiDevo; 15.03.2017
comment
Вот это да. Я никогда не знал, что фрагмент передается с экземпляром активности как с context по onAttach(), в то время как активность onCreate() еще может быть вызвана или завершена! Помогли мне понять несколько странных проблем в моем приложении. - person rpattabi; 24.01.2018

Фрагменты восстанавливаются во время действия onCreate(). Однако важно то, что они восстанавливаются в файле onCreate() базового класса Activity. Таким образом, если вы сначала вызовете super.onCreate(), все остальные методы onCreate() будут выполняться после того, как ваши фрагменты будут восстановлены.

Тогда одним из возможных решений является восстановление вашего состояния или вычисление того, какие данные потребуются вашему фрагменту ДО, когда вы вызовете super.onCreate()

Жизненный цикл выглядит так:

ACTIVITY onCreate (pre-super)
FRAGMENT onAttach
ACTIVITY onCreate (post-super)

Итак, сделайте что-то вроде этого:

@Override
public void onCreate( final Bundle savedInstanceState )
{
    Log.d( TAG, "ACTIVITY onCreate (pre-super)" );
    // Do your processing here
    super.onCreate( savedInstanceState ); // Fragments will be restored here
    Log.d( TAG, "ACTIVITY onCreate (post-super)" );
}
person Adam    schedule 13.05.2015
comment
Я не могу отблагодарить вас за этот ответ. целых 2 дня искал ответ на такую ​​проблему - person user3213851; 28.07.2015
comment
Стоит отметить, что вы можете включить «Не сохранять действия» в настройках разработчика, чтобы активировать это поведение без изменения конфигурации. - person cascal; 09.01.2017