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

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

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

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

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

Я начинаю деятельность в портретной ориентации

  • Я вызываю initLoader
  • Я получаю onCreateLoader и onLoadFinished callbacks

Затем я перехожу к пейзажу

  • Я вызываю initLoader
  • Нет onCreateLoader или onLoadFinished callbacks

Я возвращаюсь к портрету

  • Я вызываю initLoader
  • Я получаю onCreateLoader и onLoadFinished callbacks

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

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

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

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

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

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

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

Первоначальное создание (OnActivityCreated)

InitLoader -> OnCreateLoader -> OnOnStartLoading -> OnLoadFinished

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

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

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

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

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

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

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

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

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

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

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

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

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

  getLoaderManager().initLoader(0, null, this); if(!getLoaderManager().getLoader(0).isReset()) { getLoaderManager().restartLoader(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); }