Ho un sistema di caricamento dei dati impostato utilizzando un caricatore e un cursore personalizzato che funziona benissimo da Attività e Frammenti ma non c'è LoaderManager (che io possa trovare) in Servizio. Qualcuno sa perché LoaderManager è stato escluso dal servizio? Se no c'è un modo per aggirare questo?È possibile utilizzare un LoaderManager da un servizio?
risposta
Qualcuno sa perché LoaderManager è stato escluso dal servizio?
Come indicato nel altra risposta, LoaderManager
è stato esplicitamente progettato per gestire Loaders
attraverso i cicli di vita di Acivities
e Fragments
. Dal Services
non si dispone di queste modifiche alla configurazione da affrontare, utilizzando un LoaderManager
non è necessario.
Se non c'è un modo per aggirare questo?
Sì, il trucco è che non è necessario utilizzare un LoaderManager
, si può solo lavorare con il vostro Loader
direttamente, che gestirà in modo asincrono il caricamento dei dati e monitorare eventuali modifiche ai dati sottostanti per voi, che è molto meglio di interrogare i tuoi dati manualmente.
Innanzitutto, creare, registrare e iniziare a caricare il proprio Loader
quando viene creato il proprio Service
.
@Override
public void onCreate() {
mCursorLoader = new CursorLoader(context, contentUri, projection, selection, selectionArgs, orderBy);
mCursorLoader.registerListener(LOADER_ID_NETWORK, this);
mCursorLoader.startLoading();
}
Avanti, implementare OnLoadCompleteListener<Cursor>
nei vostri Service
per gestire i callback di carico.
@Override
public void onLoadComplete(Loader<Cursor> loader, Cursor data) {
// Bind data to UI, etc
}
Infine, non dimenticate ripulire il vostro Loader
quando il Service
è distrutto.
@Override
public void onDestroy() {
// Stop the cursor loader
if (mCursorLoader != null) {
mCursorLoader.unregisterListener(this);
mCursorLoader.cancelLoad();
mCursorLoader.stopLoading();
}
}
Purtroppo, no. I caricatori sono stati progettati per attività e frammenti al fine di gestire in modo pulito le modifiche alla configurazione che si verificano in Activites and Fragments. Ad esempio, ruotare il dispositivo e ricollegarlo ai dati esistenti.
Un servizio non ha modifiche di configurazione, si siederà in background fino al completamento o il sistema è obbligato ad eliminarlo. Quindi, supponendo che tu stia eseguendo il tuo codice su un thread in background nel tuo Servizio (che dovresti comunque), non c'è motivo di usare un Loader. Basta effettuare le chiamate necessarie per interrogare i dati.
Quindi se il servizio è solo un IntentService, è possibile scrivere la logica per interrogare i dati con il cursore nel metodo onHandleIntent().
è interessante. Supponiamo di essere nel bel mezzo dell'esecuzione di 'onLoadComplete' e che i dati del cursore cambino. L'esecuzione di 'onLoadComplete' si interromperà bruscamente e ricomincerà con il nuovo cursore? Sto solo cercando di capire come gestire con garbo un aggiornamento dei dati mentre si scorre il cursore in un servizio. – faizal
Da quello che ho visto, poiché 'onLoadComplete' è chiamato sul thread principale di' Service's', qualsiasi chiamata successiva a 'onLoadComplete' semplicemente impilerà ed eseguirà con un nuovo' Cursore' dopo il completamento iniziale di 'onLoadComplete'. Questo dovrebbe essere quasi esattamente uguale al comportamento che si otterrebbe con un 'LoaderManager' che chiama' onLoadFinished' da diverse modifiche successive dei dati. –
@StevenByle Penso che dovresti anche chiamare 'mCursorLoader.reset() 'per chiudere il cursore. Secondo il codice sorgente, 'reset()' chiamerà 'onStopLoading();' (che è uguale a 'stopLoading') e quindi chiuderà il cursore. Penso, altrimenti il cursore non sarà chiuso. – MyDogTom