39

У меня есть система загрузки данных, настроенная с использованием пользовательского Loader и Cursor, который отлично работает с Activity и Fragments, но в Service Service нет LoaderManager (который я могу найти). Кто-нибудь знает, почему LoaderManager был исключен из службы? Если нет, есть ли способ обойти это?Можете ли вы использовать LoaderManager из службы?

ответ

49

Кто-нибудь знает, почему 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(); 
    } 
} 
+1

это интересно. Предположим, что мы находимся где-то посередине выполнения 'onLoadComplete' и изменения данных курсора. Будет ли выполнение 'onLoadComplete' внезапно останавливаться и начинаться с нового курсора? Я просто пытаюсь понять, как грациозно обрабатывать обновление данных, итерации через курсор в службе. – faizal

+0

Из того, что я видел, так как 'onLoadComplete' вызывается в главном потоке' Service', любой последующий вызов 'onLoadComplete' просто складывался бы и выполнялся бы с новым' Cursor' после завершения начальных 'onLoadComplete'. Это должно быть почти точно так же, как и поведение, которое вы получили бы с вызовом 'LoaderManager'' onLoadFinished' из нескольких последующих изменений данных. –

+0

@StevenByle Я думаю, вы также должны вызвать 'mCursorLoader.reset() ', чтобы закрыть курсор. Согласно исходному коду, 'reset()' вызовет 'onStopLoading();' (который равен 'stopLoading'), а затем закроет курсор. Я думаю, иначе курсор не будет закрыт. – MyDogTom

17

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

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

Так что если ваша Служба - это просто IntentService, вы можете написать свою логику, чтобы запросить данные с поддержкой курсора в методе onHandleIntent().

http://developer.android.com/guide/components/loaders.html