39

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

49

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(); 
    } 
} 
+1

è 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

+0

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. –

+0

@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

17

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().

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

Problemi correlati