LoaderManager con più caricatori: come ottenere il corretto cursorloader


116

Per me non è chiaro come ottenere il cursore destro se hai più caricatori. Supponiamo che tu definisca due diversi Loader con:

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

quindi in onCreateLoader () fai cose diverse a seconda dell'id:

@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;
} 

Fin qui tutto bene. Ma come ottenere il cursore destro in onLoadFinished () perché non si ottiene alcun ID per identificare il cursore corretto per il Cursoradapter corretto.

@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 mi sbaglio e questo è il modo sbagliato per ottenere risultati per due diversi cursoriadapter in un frammento.


Questa è davvero una buona domanda! È ben chiesto e tocca un argomento abbastanza sfumato. Molto specifico.
Kurtis Nusbaum

7
Va detto che è necessario utilizzare classi gestori separate ogni volta che il tipo restituito dal caricatore non è lo stesso su tutti i caricatori, poiché a causa della cancellazione del tipo generico, Java non consente di implementare un'interfaccia ( LoaderCallbacksin questo caso) con più di una genere. Funziona semplicemente nel tuo caso poiché entrambe le volte, il risultato è un file Cursor.
Matthias

1
@Matthias Fantastico l'avevi menzionato! Sto solo considerando come avere 2 caricatori con diverso tipo di ritorno. Quindi cosa succede se 2 caricatori con 2 diversi tipi di ritorno? Esegui un'attività con 1 caricatore e un'altra con thread?
Robert

@Robert Non c'è bisogno di usare il thread. Puoi usare due Loaders. Si prega di passare attraverso questo stackoverflow.com/a/20839825/2818583
AnV

Risposte:


119

La classe Loader ha un metodo chiamato getId () . Spero che questo restituisca l'id che hai associato al caricatore.


Grazie, Kurtis! Freddo! Lo proverò ma mi aspetto che funzioni. Ho avuto la stessa idea ma non ho guardato l'oggetto caricatore. Ho invece dato un'occhiata all'oggetto cursore ...
Kay Gladen

Funziona con Loader.getID ()! Ho ricontrollato questo adesso. Grande!
Kay Gladen

2
Sto pensando di farlo usando classi interne / anonime, in modo che ogni caricatore abbia il proprio oggetto che ottiene i callback.
Jords

@KurtisNusbaum, perché sarebbe sbagliato? La classe interna verrebbe distrutta insieme all'attività esterna, quindi questo non dovrebbe comportare una perdita di memoria o altro. Una classe statica con un forte riferimento all'attività è semanticamente equivalente a una classe interna (che mantiene un forte riferimento implicito alla classe esterna).
Matthias

6
@Jords È tecnicamente corretto. Non ne sto discutendo. Ma perché fare tutta quella tiritera quando puoi semplicemente chiamare getId()?
Kurtis Nusbaum

32

Usa il metodo getId () di 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;
    }
}    

8

Se i tuoi caricatori non hanno nulla in comune tranne il tipo di classe del risultato (qui :) Cursor, è meglio creare due LoaderCallbacksistanze separate (semplicemente come due classi interne nella tua Attività / Frammento), ognuna dedicata a un trattamento del caricatore, piuttosto che provare a mescolare le mele con le arance.

Nel tuo caso sembra che sia l'origine dati che il trattamento dei risultati siano diversi, il che richiede di scrivere il codice boilerplate aggiuntivo per identificare lo scenario corrente e inviarlo al blocco di codice appropriato.


Ho una domanda. Lo scopo Activitydell'implementazione LoaderCallbackse del passaggio thisa getLoaderManager().initLoader()è garantire che LoaderManagerfunga da canale di comunicazione tra Activitye Loadervia LoaderCallbacks. Come viene creato quel canale di comunicazione qui poiché Activitynon sta implementando LoaderCallbacksma piuttosto creando classi interne anonime?
AnV

3
Il canale di comunicazione è il LoaderCallbacks. Niente richiede di utilizzare lo Activitystesso come LoaderCallbacks. È più semplice creare più canali di comunicazione quando ne hai bisogno.
BladeCoder
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.