Иногда не вызывать обратный вызов onCreateLoader после вызова initLoader - PullRequest
11 голосов
/ 18 октября 2011

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

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

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

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

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

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

Затем я изменяю на альбомную

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

Я изменяю обратно на портрет

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

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

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

Ответы [ 7 ]

10 голосов
/ 13 ноября 2012

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

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

4 голосов
/ 09 декабря 2011

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

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

2 голосов
/ 14 мая 2012

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

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

initLoader -> OnCreateLoader -> OnOnStartLoading -> OnLoadFinished

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

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

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

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

1 голос
/ 14 ноября 2014

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

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

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

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

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

getLoaderManager().initLoader( 0, null, this );
0 голосов
/ 25 июля 2017

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

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

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

    if (loader == null) {
        getActivity().getLoaderManager().initLoader(LOADERID, null, this);
    } else {
        getActivity().getLoaderManager().restartLoader(LOADERID, null, this);
    }
0 голосов
/ 09 декабря 2015

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

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

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

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

0 голосов
/ 12 февраля 2014

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

...