LoaderManager z wieloma programami ładującymi: jak uzyskać właściwy program ładujący kursor

116

Nie jest dla mnie jasne, jak uzyskać właściwy kursor, jeśli masz wiele programów ładujących. Powiedzmy, że definiujesz dwa różne programy ładujące za pomocą:

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

następnie w onCreateLoader () robisz różne rzeczy w zależności od 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;
} 

na razie w porządku. Ale jak uzyskać właściwy kursor w onLoadFinished (), ponieważ nie dostajesz żadnego identyfikatora do zidentyfikowania właściwego kursora dla odpowiedniego adaptera Cursor.

@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

czy też się mylę i jest to niewłaściwy sposób uzyskania wyników dla dwóch różnych adapterów kursora w jednym fragmencie.

Kay Gladen
źródło
To naprawdę dobre pytanie! Jest dobrze zadany i porusza dość zniuansowany temat. Bardzo specyficzny.
Kurtis Nusbaum
7
Należy wspomnieć, że mają używać oddzielnych klas procedur obsługi, gdy zwracany typ ładowarka nie jest taka sama we wszystkich ładowarek, ponieważ ze względu na ogólny typ skasowaniem, Java nie pozwala zaimplementować interfejs ( LoaderCallbacksw tym przypadku) z więcej niż jednego rodzaj. Po prostu działa w twoim przypadku, ponieważ za każdym razem wynikiem jest Cursor.
Matthias
1
@Matthias Great, wspomniałeś o tym! Zastanawiam się tylko, jak mieć 2 ładowarki z innym typem powrotu. A co jeśli 2 ładowarki z 2 różnymi typami powrotu? Czy jedno zadanie z 1 programem ładującym, a drugie z wątkiem?
Robert,
@Robert Nie ma potrzeby używania wątku. Możesz użyć dwóch Loaders. Przejdź przez ten stackoverflow.com/a/20839825/2818583
AnV,

Odpowiedzi:

119

Klasa Loader ma metodę o nazwie getId () . Mam nadzieję, że zwróci to identyfikator powiązany z programem ładującym.

Kurtis Nusbaum
źródło
Dzięki, Kurtis! Chłodny! Spróbuję, ale spodziewam się, że zadziała. Miałem ten sam pomysł, ale nie patrzyłem na obiekt ładujący. Zamiast tego
rzuciłem
Działa z Loader.getID ()! Właśnie to dwukrotnie sprawdziłem. Wspaniały!
Kay Gladen
2
Myślę o zrobieniu tego przy użyciu klas wewnętrznych / anonimowych, tak aby każdy program ładujący miał swój własny obiekt pobierający wywołania zwrotne.
Jords
@KurtisNusbaum, dlaczego miałoby to być nieprawidłowe? Klasa wewnętrzna zostałaby zniszczona wraz z działaniem zewnętrznym, więc nie powinno to spowodować wycieku pamięci ani niczego takiego. Klasa statyczna z silnym odniesieniem do Activity jest semantycznie równoważna klasie wewnętrznej (która zachowuje niejawne silne odniesienie do klasy zewnętrznej).
Matthias,
6
@Jords Jest technicznie poprawne. Nie debatuję nad tym. Ale po co robić to wszystko, skoro możesz po prostu zadzwonić getId()?
Kurtis Nusbaum
32

Użyj metody getId () modułu ładującego :

@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
źródło
8

Jeśli twoje programy ładujące nie mają nic wspólnego poza typem klasy wyniku (tutaj Cursor:), lepiej jest utworzyć dwie oddzielne LoaderCallbacksinstancje (po prostu jako dwie klasy wewnętrzne w twoim Activity / Fragment), z których każda jest przeznaczona do jednego traktowania modułu ładującego. niż mieszanie jabłek z pomarańczami.

W twoim przypadku wydaje się, że zarówno źródło danych, jak i sposób przetwarzania wyników są różne, co wymaga napisania dodatkowego standardowego kodu, aby zidentyfikować bieżący scenariusz i wysłać go do odpowiedniego bloku kodu.

BladeCoder
źródło
Mam jedno pytanie. Celem Activitywdrożenia LoaderCallbacksi przejścia thisdo getLoaderManager().initLoader()jest zapewnienie, że LoaderManagerdziała jako kanał komunikacji między Activityi Loaderza pośrednictwem LoaderCallbacks. Jak powstaje ten kanał komunikacyjny, który Activitynie jest implementacją, LoaderCallbacksale raczej tworzeniem anonimowych klas wewnętrznych?
AnV
3
Kanałem komunikacji jest LoaderCallbacks. Nic nie wymaga używania Activitysamego siebie jako LoaderCallbacks. Łatwiej jest stworzyć wiele kanałów komunikacji, kiedy ich potrzebujesz.
BladeCoder