У меня есть система загрузки данных, настроенная с использованием пользовательского Loader и Cursor, который отлично работает с Activity и Fragments, но в Service Service нет LoaderManager (который я могу найти). Кто-нибудь знает, почему LoaderManager был исключен из службы? Если нет, есть ли способ обойти это?Можете ли вы использовать LoaderManager из службы?
ответ
Кто-нибудь знает, почему LoaderManager был исключен из службы?
Как указано в другом ответе, LoaderManager
был явно предназначен для управления Loaders
через жизненный цикл от Acivities
и Fragments
. Поскольку Services
не имеют этих изменений конфигурации для работы, использование LoaderManager
не требуется.
Если нет пути вокруг этого?
Да, фокус в том, что вам не нужно использовать LoaderManager
, вы можете просто работать с Loader
непосредственно, который будет обрабатывать асинхронно загрузки данных и мониторинга любых лежащих в основе изменения данных для вас, что гораздо лучше чем запрос данных вручную.
Во-первых, создайте, зарегистрируйте и начните загрузку Loader
, когда будет создан ваш Service
.
@Override
public void onCreate() {
mCursorLoader = new CursorLoader(context, contentUri, projection, selection, selectionArgs, orderBy);
mCursorLoader.registerListener(LOADER_ID_NETWORK, this);
mCursorLoader.startLoading();
}
Далее реализовать OnLoadCompleteListener<Cursor>
в ваших Service
для обработки обратных вызовов нагрузки.
@Override
public void onLoadComplete(Loader<Cursor> loader, Cursor data) {
// Bind data to UI, etc
}
Наконец, не забудьте очистить ваш Loader
когда Service
разрушается.
@Override
public void onDestroy() {
// Stop the cursor loader
if (mCursorLoader != null) {
mCursorLoader.unregisterListener(this);
mCursorLoader.cancelLoad();
mCursorLoader.stopLoading();
}
}
К сожалению, нет. Погрузчики были разработаны для действий и фрагментов, чтобы полностью обрабатывать изменения конфигурации, которые происходят в Activites и Fragments. т. е. вращение вашего устройства и повторное присоединение к существующим данным.
Сервис не имеет каких-либо изменений конфигурации, он будет сидеть в фоновом режиме, пока он не завершится, или система не будет вынуждена его убить. Поэтому, предполагая, что вы выполняете свой код в фоновом потоке в своем сервисе (каким бы вы ни были в любом случае), у них просто нет причин использовать загрузчик. Просто выполните вызовы, необходимые для запроса ваших данных.
Так что если ваша Служба - это просто IntentService, вы можете написать свою логику, чтобы запросить данные с поддержкой курсора в методе onHandleIntent().
это интересно. Предположим, что мы находимся где-то посередине выполнения 'onLoadComplete' и изменения данных курсора. Будет ли выполнение 'onLoadComplete' внезапно останавливаться и начинаться с нового курсора? Я просто пытаюсь понять, как грациозно обрабатывать обновление данных, итерации через курсор в службе. – faizal
Из того, что я видел, так как 'onLoadComplete' вызывается в главном потоке' Service', любой последующий вызов 'onLoadComplete' просто складывался бы и выполнялся бы с новым' Cursor' после завершения начальных 'onLoadComplete'. Это должно быть почти точно так же, как и поведение, которое вы получили бы с вызовом 'LoaderManager'' onLoadFinished' из нескольких последующих изменений данных. –
@StevenByle Я думаю, вы также должны вызвать 'mCursorLoader.reset() ', чтобы закрыть курсор. Согласно исходному коду, 'reset()' вызовет 'onStopLoading();' (который равен 'stopLoading'), а затем закроет курсор. Я думаю, иначе курсор не будет закрыт. – MyDogTom