Когда вы вызываете initLoader во Фрагменте?

У меня довольно простой фрагмент с ListView, CursorLoader и CursorAdapter. Все в одной активности (просто переключение фрагментов). Моя проблема в том, что onLoadFinished() вызывается в некоторых ситуациях дважды в зависимости от того, где я поместил вызов initLoader(). Эти ситуации:

  • изменение конфигурации (вращающийся экран и т.д.)
  • заменяя текущий фрагмент другим, используя FragmentTransaction, а затем возвращаем назад (popping backstack). В этом случае фрагмент детали одного элемента списка.

Когда initLoader() помещается в onCreateView(), onActivityCreated() (рекомендуется в документации) onLoadFinished() вызывается дважды после изменения конфигурации. Есть объяснение, почему Рудик Краснийнос. Но onLoadFinished() вызывается только один раз при появлении нового фрагмента из backstack.

Когда initLoader() помещается в onResume()/onStart(), то ситуация сверху отменяется. Два вызова onLoadFinished() для вызова backstack и один для изменения конфигурации.

Таким образом, вопрос заключается в том, где и как запустить Loader без вызова onLoadFinished() дважды или что проверить, чтобы не запускать загрузчик дважды. Спасибо!

Код для замены фрагмента:

FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.root_view, fragment, tag);
ft.addToBackStack(null);
ft.commit();

Код для CursorAdapter:

//onCreateView
MyCursorAdapter mAdapter = new MyCursorAdapter(getActivity(), null, 0);
mList.setAdapter(mAdapter);
//in other/same lifecycle callbacks
getLoaderManager().initLoader(ID, null, this);

Я использую библиотеку поддержки v18.

Ответы

Ответ 1

Чтобы избежать onLoadFinished для вызова более одного раза, запустите свой загрузчик в onResume.

Ответ 2

Я называю это in onCreate, и насколько я знаю, это лучшая практика... Я использую его прямо сейчас, и все работает отлично.

@Override
    protected void onCreate(Bundle savedInstanceState)

                             .......

          getSupportLoaderManager().initLoader(LOADER_ID, null, this);

                             .......
}

Ответ 3

Назовите его onActivityCreated(Bundle savedInstanceState) в своем фрагменте

getLoaderManager().initLoader(LOADER_ID, new Bundle(), this);

Ответ 4

Как насчет проверки savedInstanceState перед запуском загрузчика.

if (savedInstanceState == null)
    getLoaderManager().initLoader(LOADER_ID, null, this);