LoaderManager con múltiples cargadores: cómo obtener el cargador de cursor correcto

116

Para mí, no está claro cómo obtener el cursor correcto si tiene varios cargadores. Digamos que define dos cargadores diferentes con:

getLoaderManager().initLoader(0,null,this);
getLoaderManager().initLoader(1,null,this);

luego en onCreateLoader () haces diferentes cosas dependiendo de la identificación:

@Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {

    if (id==0){
               CursorLoader loader = new CursorLoader(getActivity(),
            MaterialContentProvider.CONTENT_URI,null,null,null,null);
    }else{
               CursorLoader loader = new CursorLoader(getActivity(),
            CustomerContentProvider.CONTENT_URI,null,null,null,null);
            };
    return loader;
} 

Hasta aquí todo bien. Pero cómo obtener el cursor correcto en onLoadFinished () porque no obtiene ninguna identificación para identificar el Cursor correcto para el Cursoradapter correcto.

@Override
public void onLoadFinished(Loader<Cursor> arg0, Cursor cursor) {


    mycursoradapter1.swapCursor(cursor);
    if(isResumed()){
        setListShown(true);
    }else {
        setListShownNoAnimation(true);
    }



}
//and where to get the cursor for mycursoradapter2

o me equivoco y esta es la forma incorrecta de obtener resultados para dos cursorapteros diferentes en un fragmento.

Kay Gladen
fuente
¡Esta es una muy buena pregunta! Está bien planteado y toca un tema bastante matizado. Muy especifico.
Kurtis Nusbaum
7
Cabe mencionar que tiene que utilizar las clases de controlador independientes siempre el tipo de retorno cargador no es la misma en todos los cargadores, ya que debido a la supresión de tipo genérico, Java no permite a implementar una interfaz ( LoaderCallbacksen este caso) con más de una tipo. Simplemente funciona en su caso, ya que en ambas ocasiones, el resultado es un Cursor.
Matthias
1
@Matthias ¡Genial, lo habías mencionado! Solo estoy considerando cómo tener 2 cargadores con diferentes tipos de retorno. Entonces, ¿qué pasa si 2 cargadores con 2 tipos de devolución diferentes? ¿Hacer una tarea con 1 cargador y otra con hilo en su lugar?
Robert
@Robert No es necesario usar hilo. Puede utilizar dos Loaders. Consulte este stackoverflow.com/a/20839825/2818583
AnV el

Respuestas:

119

La clase Loader tiene un método llamado getId () . Espero que esto devuelva la identificación que ha asociado con el cargador.

Kurtis Nusbaum
fuente
¡Gracias, Kurtis! ¡Frio! Lo intentaré, pero espero que funcione. Tuve la misma idea pero no miré el objeto cargador. En su lugar
he echado
¡Funciona con Loader.getID ()! He comprobado esto ahora mismo. ¡Excelente!
Kay Gladen
2
Estoy pensando en hacer esto usando clases internas / anónimas, de modo que cada cargador tenga su propio objeto recibiendo las devoluciones de llamada.
Jords
@KurtisNusbaum, ¿por qué sería incorrecto? La clase interna se destruiría junto con la actividad externa, por lo que esto no debería resultar en una pérdida de memoria ni nada. Una clase estática con una fuerte referencia a la Actividad es semánticamente equivalente a una clase interna (que mantiene una fuerte referencia implícita a la clase externa).
Matthias
6
@Jords Es técnicamente correcto. No estoy debatiendo eso. Pero, ¿por qué todo ese rigamarole cuando puedes llamar getId()?
Kurtis Nusbaum
32

Utilice el método getId () de Loader:

@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
    switch (loader.getId()) {
        case 0:
            // do some stuff here
            break;
        case 1:
            // do some other stuff here
            break;
        case 2:
            // do some more stuff here
            break;
        default:
            break;
    }
}    
IgorGanapolsky
fuente
8

Si sus cargadores no tienen nada en común más que el tipo de clase del resultado (aquí :) Cursor, es mejor que cree dos LoaderCallbacksinstancias separadas (simplemente como dos clases internas en su Actividad / Fragmento), cada una dedicada a un tratamiento de cargador, en lugar de que intentar mezclar manzanas con naranjas.

En su caso, parece que tanto la fuente de datos como el tratamiento del resultado son diferentes, lo que requiere que escriba el código repetitivo adicional para identificar el escenario actual y enviarlo al bloque de código apropiado.

BladeCoder
fuente
Tengo una pregunta. El propósito de Activityimplementar LoaderCallbacksy pasar thisa getLoaderManager().initLoader()es asegurar que LoaderManageractúa como canal de comunicación entre Activityy Loadervía LoaderCallbacks. ¿Cómo se está creando aquí ese canal de comunicación si Activityno se está implementando LoaderCallbackssino creando clases internas anónimas?
2016
3
El canal de comunicación es el LoaderCallbacks. Nada requiere usar el Activitymismo como LoaderCallbacks. Es más sencillo crear múltiples canales de comunicación cuando los necesita.
BladeCoder