Иногда не вызывать обратный вызов onCreateLoader после вызова initLoader

У меня есть действие, которое вызывает initLoader при его создании, чтобы загрузить данные, которые будет отображаться в действии. Обычно это работает нормально. У меня установлены контрольные точки, чтобы увидеть порядок, в котором все происходит. Сначала я вызываю initLoader, затем получаю обратный вызов OnCreateLoader, затем обратный вызов OnLoadFinished, затем все отлично.

Однако я заметил, что, если я изменил ориентацию на своем Android, я не получаю обратный вызов OnCreateLoader или обратный вызов OnLoadFinished, в результате чего на странице не отображаются данные. Я по-прежнему получаю точку останова при вызове initLoader, поэтому я знаю, что это происходит, но я не получаю сообщение об ошибке и не могу найти документацию, объясняющую, почему я не получу обратный вызов после вызова initLoader.

Интересно, что я получаю обратные вызовы, если я возвращаюсь к первоначальной ориентации.

Итак, подведем итог:

Начинаю занятие в портретной ориентации

  • Я звоню initLoader
  • Я получаю обратные вызовы onCreateLoader и onLoadFinished

Затем я перехожу в ландшафт

  • Я звоню initLoader
  • нет обратных вызовов onCreateLoader или onLoadFinished

Я перехожу на портрет

  • Я звоню initLoader
  • Я получаю обратные вызовы onCreateLoader и onLoadFinished

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

Кто-нибудь знает, что происходит?

7 ответов

Мы видели эту же проблему с фрагментами в ViewPager. Похоже, что загрузчики не активируются должным образом при возобновлении фрагмента. Фактически, когда фрагмент приостановлен, наш CursorLoader больше не получает обратные вызовы ContentObserver, как я ожидал.

Наш обходной путь состоял в том, чтобы вызвать restartLoader(), который сбрасывает предыдущее содержимое и перезагружает данные. Это будет иметь тот же сетевой эффект, что и destroyLoader (); initLoader(), но он будет более эффективным.

Вам нужно будет вызвать initLoader в вашем onCreate

Для аналогичной проблемы и дополнительной информации посмотрите LoaderCallbacks.onLoadFinished не вызывается, если изменение ориентации происходит во время запуска AsyncTaskLoader

Я отслеживаю эту проблему

Начальное создание (OnActivityCreated)

initLoader -> OnCreateLoader -> OnOnStartLoading -> OnLoadFinished

Изменение ориентации - OnActivityCreated вызывается снова

initLoader - OnLoadFinished (без загрузки каких-либо данных!) - ошибка.

Единственный обходной путь, который я нашел, - это вызвать destroyLoader() непосредственно перед init. Это заставляет произойти правильную последовательность создания / запуска / завершения.

Кажется, что происходит, что код initLoader написан так, чтобы предположить, что фрагмент не разрушается во время изменения ориентации, что, конечно, не так, как работает остальная часть Android.

У меня было нечто очень похожее, что происходило с адаптерами курсора во фрагментах при изменении ориентации. initloader вызывался в onCreateView (также пробовал onStart и onResume), но onCreatLoader, а также другие методы обратного вызова загрузчика никогда не вызывались. Также следует отметить, что в моем случае фрагмент содержался в пейджере просмотра.

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

В моем случае исправление менялось так:

getActivity().getLoaderManager().initLoader( 0, null, this );

Я изменил это на это

getLoaderManager().initLoader( 0, null, this );

У меня недавно была эта проблема, и я хотел бы представить свое решение.

Я обнаружил, что достаточно просто сделать:

    Loader<Cursor> loader = getActivity().getLoaderManager().getLoader(LOADERID);

    if (loader == null) {
        getActivity().getLoaderManager().initLoader(LOADERID, null, this);
    } else {
        getActivity().getLoaderManager().restartLoader(LOADERID, null, this);
    }

Я потратил недели на отслеживание этой проблемы. Надоело помещать содержимое предыдущего фрагмента в мой новый фрагмент. Наконец исправлено.

В моем методе onCreate(), фрагмент которого реализовал LoaderManager, я сделал это

  getLoaderManager().initLoader(0, null, this);
        if(!getLoaderManager().getLoader(0).isReset()) {
            getLoaderManager().restartLoader(0, null, this);
        }

Это работает, когда новый загрузчик не был активирован должным образом.

Это старый вопрос, но, может быть, кого-то все равно волнует... У меня была такая же проблема, и я смог ее исправить. Вот ссылка: onCreateLoader не вызывается при изменении ориентации

Другие вопросы по тегам