Ответ 1
Обновленный ответ:
Каковы сценарии, в которых я могу попасть в беду?
При добавлении Fragment
в задний стек и передачи Bundle
в Fragment
от onSaveInstanceState()
до onCreateView()
при изменении конфигурации. Вызов setRetainInstance(true)
установит для параметра Bundle
значение null при изменении конфигурации.
(я не уверен, что разработчик действительно попытался бы это сделать, поскольку использование setRetainInstance(true)
делает onSaveInstanceState()
избыточным, но я не видел поведения, задокументированного в документах API, поэтому я написал этот ответ).
Если вызываются как addToBackStack()
, так и setRetainInstance(true)
, setRetainInstance()
частично изменяет вызовы метода жизненного цикла Fragment
и значения параметров при изменениях конфигурации по сравнению с вызывающим только addToBackStack()
.
В частности, в нижеприведенном тесте, рассматривая различия между вызовом только addToBackStack()
и вызовом setRetainInstance(true)
, и выясняя, что происходит при изменении конфигурации:
Вызов addToBackStack()
, но не setRetainInstance(true)
;
-
onCreate()
иonDestroy()
. - пучок, переданный из
onSaveInstanceState()
, принимается как параметр вonCreateView()
.
Вызов как addToBackStack()
, так и setRetainInstance(true)
:
-
onCreate()
иonDestroy()
не вызываются. Это подтверждается документами API. - пучок, переданный из
onSaveInstanceState()
, не получен вonCreateView()
. ПереданныйBundle
имеет значение null.
Тест с зарегистрированными вызовами метода и параметрами, проверенными на null:
В Activity
:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyFragment fragment;
if (savedInstanceState != null) {
fragment = (MyFragment) getFragmentManager().findFragmentByTag("my_fragment_tag");
} else {
fragment = new MyFragment();
FragmentTransaction t = getFragmentManager().beginTransaction();
t.addToBackStack(null);//toggle this
t.add(android.R.id.content, fragment, "my_fragment_tag").commit();
}
}
В Fragment
:
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setRetainInstance(true);//toggle this
}
и
@Override
public void onSaveInstanceState(Bundle outState) {
outState.putString("test", "value");
super.onSaveInstanceState(outState);
}
Тест 1: жизненный цикл фрагмента при вызове addToBackStack()
, а setRetainInstance(true)
- not, называемый
- onAttach()
- OnCreate()
- onCreateView()
- onActivityCreated()
- OnStart()
- onResume()
[Устройство повернуто от портрета к пейзажу]
- OnPause()
- onSaveInstanceState()
- OnStop()
- onDestroyView()
- OnDestroy()
- onDetach()
- onAttach()
- OnCreate()
- onCreateView() с пакетом param!= null
- OnStart()
- onResume()
Тестирование 2 и 3: вызовы жизненного цикла фрагмента с вызываемым setRetainInstance(true)
, addToBackStack()
вызванным/не вызываемым (тот же результат):
- onAttach()
- onCreateView()
- onActivityCreated()
- OnStart()
- onResume()
[Устройство повернуто от портрета к пейзажу]
- OnPause()
- onSaveInstanceState()
- OnStop()
- onDestroyView()
- onDetach()
- onAttach()
- onCreateView() с пакетом param == null
- OnStart()
- onResume()