Иногда не вызывать обратный вызов 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 не вызывается при изменении ориентации