Жизненные циклы фрагментов/активностей и изменение ориентации

Фрагменты — забавные вещи, но я подумал, что если вы узнаете их особенности, они станут бесценным инструментом для написания хорошего кода на нескольких устройствах.

Однако при исправлении ошибки изменения ориентации я наткнулся на стену. Чтобы мой фрагмент работал, ему нужен доступ к представлению, которое принадлежит ему, содержащему активность, что приводит меня к веселой погоне, пытаясь выяснить, как взаимодействуют жизненные циклы активности и фрагмента.

Я добавляю фрагмент в представление «Действия» в методе onCreate():

// Only add a fragment once, as after it's been added it cannot be replaced (Even though there is a .replace() method. Which is a massive gaping hole in fragments as a technology if you ask me)
if(savedInstanceState == null) {
    MainMenuFragment menu= new MainMenuFragment();
    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();   
    transaction.replace(R.id.menuFrame, menu);  
    transaction.commit();
}

Приведение к этому жизненному циклу Activity->Fragment:

01-04 15:17:27.226: W/SinglePaneActivity 0:   onCreate()
01-04 15:17:27.378: W/MainMenuFragment   0:   onAttach() to SinglePaneActivity 0
01-04 15:17:27.378: W/MainMenuFragment   0:   onCreate()
01-04 15:17:27.453: W/MainMenuFragment   0:   onActivityCreated()
01-04 15:17:27.476: W/MainMenuFragment   0:   onStart()
01-04 15:17:27.476: W/SinglePaneActivity 0:   onStart()
01-04 15:17:27.476: W/SinglePaneActivity 0:   onResume()
01-04 15:17:27.476: W/MainMenuFragment   0:   onResume()

Однако изменение ориентации показывает, что обычно это не так. Метод фрагмента onCreate() не вызывается после родительского действия onCreate(). Фактически, первый вызов жизненного цикла фрагмента onAttach() происходит еще до того, как действие было создано (null передается в качестве аргумента):

01-04 15:10:49.589: W/MainMenuFragment   0:   onPause()
01-04 15:10:49.589: W/SinglePaneActivity 0:   onPause()
01-04 15:10:49.589: W/MainMenuFragment   0:   onStop()
01-04 15:10:49.589: W/SinglePaneActivity 0:   onStop()
01-04 15:10:49.589: W/MainMenuFragment   0:   onDestroyView()
01-04 15:10:49.589: W/MainMenuFragment   0:   onDestroy()
01-04 15:10:49.589: W/MainMenuFragment   0:   onDetach()
01-04 15:10:49.609: W/SinglePaneActivity 0:   onDestroy()
01-04 15:10:49.617: W/MainMenuFragment   1:   onAttach() to null
01-04 15:10:49.617: W/MainMenuFragment   1:   onCreate()
01-04 15:10:49.617: W/SinglePaneActivity 1:   onCreate()
01-04 15:10:49.890: W/MainMenuFragment   1:   onActivityCreated()
01-04 15:10:49.917: W/MainMenuFragment   1:   onStart()
01-04 15:10:49.917: W/SinglePaneActivity 1:   onStart()
01-04 15:10:49.921: W/SinglePaneActivity 1:   onResume()
01-04 15:10:49.921: W/MainMenuFragment   1:   onResume()

Я совершенно не понимаю, почему это происходит. Может ли кто-нибудь пролить свет на то, почему Fragment.onAttach() вызывается до того, как он содержит Activity?

Фрагменты, которые у меня есть, которым не нужен доступ к их содержащей активности (до взаимодействия с пользовательским интерфейсом), работают, как и ожидалось.


person Graeme    schedule 04.01.2012    source источник


Ответы (1)


Арх,

01-04 15:46:23.175: W/MainMenuFragment   0: onAttach() to SinglePaneActivity 0
01-04 15:46:23.179: W/MainMenuFragment   0: onCreate()
01-04 15:46:23.246: W/MainMenuFragment   0: onActivityCreated() with Activity SinglePaneActivity 0
01-04 15:46:23.269: W/MainMenuFragment   0: onStart()
01-04 15:46:23.269: W/SinglePaneActivity 0: onStart()

Почему, черт возьми, существует метод onAttach(), я понятия не имею. Тем более, что «присоединение» происходит до того, как произойдет действие.

Конечно, мне нужен был метод onActivityCreated(), который происходит как последний вызов в наборе «Создание» Fragment. события жизненного цикла.

person Graeme    schedule 04.01.2012