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.


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.


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

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.


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
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.