39

Tengo un sistema de carga de datos configurado usando un Cargador y Cursor personalizado que funciona muy bien desde Actividades y Fragmentos, pero no hay un LoaderManager (que puedo encontrar) en el Servicio. ¿Alguien sabe por qué LoaderManager fue excluido del servicio? Si no hay una forma de evitar esto?¿Se puede usar un LoaderManager de un servicio?

Respuesta

49

¿Alguien sabe por qué LoaderManager fue excluido de servicio?

Como se indica en la otra respuesta, LoaderManager fue diseñado expresamente para gestionar Loaders a través de los ciclos de vida de Acivities y Fragments. Dado que Services no tiene que hacer frente a estos cambios de configuración, no es necesario utilizar LoaderManager.

¿Si no hay una forma de evitar esto?

Sí, el truco es que no es necesario utilizar un LoaderManager, sólo puede trabajar con su Loader directamente, que se encargará de cargar de forma asíncrona sus datos y el seguimiento de los cambios de datos subyacentes para usted, lo cual es mucho mejor que consultar sus datos manualmente.

Primero, cree, regístrese y comience a cargar su Loader cuando se cree Service.

@Override 
public void onCreate() { 
    mCursorLoader = new CursorLoader(context, contentUri, projection, selection, selectionArgs, orderBy); 
    mCursorLoader.registerListener(LOADER_ID_NETWORK, this); 
    mCursorLoader.startLoading(); 
} 

A continuación, poner en práctica en sus OnLoadCompleteListener<Cursor>Service devoluciones de llamada de carga para manejar.

@Override 
public void onLoadComplete(Loader<Cursor> loader, Cursor data) { 
    // Bind data to UI, etc 
} 

Por último, no se olvide de limpiar su Loader cuando el Service se destruye.

@Override 
public void onDestroy() { 

    // Stop the cursor loader 
    if (mCursorLoader != null) { 
     mCursorLoader.unregisterListener(this); 
     mCursorLoader.cancelLoad(); 
     mCursorLoader.stopLoading(); 
    } 
} 
+1

eso es interesante. Supongamos que estamos en el medio de ejecutar 'onLoadComplete' y los datos del cursor cambian. ¿La ejecución de 'onLoadComplete' se detendrá abruptamente y comenzará de nuevo con el nuevo cursor? Solo estoy tratando de comprender cómo gestionar con elegancia una actualización de datos mientras se itera por el cursor en un servicio. – faizal

+0

Por lo que he visto, dado que se llama a 'onLoadComplete' en el hilo principal' Service', cualquier llamada posterior a 'onLoadComplete' simplemente se apilaría y se ejecutaría con un nuevo' Cursor' luego de que 'onLoadComplete' terminara. Esto debería ser casi exactamente el mismo comportamiento que obtendría con un 'LoaderManager' llamando a' onLoadFinished' de varios cambios de datos posteriores. –

+0

@StevenByle Creo que también debería llamar a 'mCursorLoader.reset() 'para cerrar el cursor. De acuerdo con el código fuente, 'reset()' llamará a 'onStopLoading();' (que es igual a 'stopLoading') y luego cerrará el cursor. Creo que, de lo contrario, el cursor no se cerrará. – MyDogTom

17

Lamentablemente, no. Los cargadores se diseñaron para actividades y fragmentos a fin de manejar limpiamente los cambios de configuración que ocurren en Activites y Fragments. es decir, girar el dispositivo y volver a conectarlo a los datos existentes.

Un servicio no tiene ningún cambio de configuración, se quedará en segundo plano hasta que se complete o el sistema se vea obligado a matarlo. Por lo tanto, suponiendo que está ejecutando su código en una cadena de fondo en su Servicio (que debería ser de todos modos), no hay razón para usar un cargador. Simplemente realice las llamadas que necesita para consultar sus datos.

Por lo tanto, si su servicio es solo un servicio intencionado, puede escribir su lógica para consultar los datos respaldados por el cursor en el método onHandleIntent().

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

Cuestiones relacionadas