2012-03-20 12 views
7

Mam działanie, które używa dwóch programów ładujących. Każdy z nich zwraca inny typ danych. Aby pobrać dane z jednego programu ładującego, wystarczy wdrożyć LoaderCallbacks<D> w działaniu. Chyba mógłbym zaimplementować LoaderCallbacks<Object> i sprawdzić typ obiektu, a następnie zdecydować, który z dwóch LoaderCallbacks jest, ale wydaje mi się, że to hack (głównie ze względu na brak bezpieczeństwa typu tutaj).LoaderCallbacks jako statyczna klasa wewnętrzna (w celu obsługi wielu programów ładujących z różnymi typami danych zwróconych)

Więc pomyślałem o zrobieniu LoaderCallbacks obiekt statyczny klasę wewnętrzną, coś takiego:

private static class geocoderLoaderCallbacks implements LoaderCallbacks<List<Address>>{ 

    @Override 
    public Loader<List<Address>> onCreateLoader(int arg0, Bundle arg1) { 
     GeocoderTask loader = new GeocoderTask(context, ""); 
     return loader; 
    } 

    @Override 
    public void onLoadFinished(Loader<List<Address>> loader, List<Address> data) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void onLoaderReset(Loader<List<Address>> loader) { 
     // TODO Auto-generated method stub 

    } 


} 

a następnie za lm.initLoader(0, null, geocoderLoaderCallbacks).

Powstaje dwa pytanie: czy można to zrobić, czy raczej powinienem trzymać się realizacji funkcji LoaderCallbacks w działaniu? I w jaki sposób bezpiecznie przekazać kontekst do onCreateLoader? Czy powinienem po prostu stworzyć konstruktora w geocoderLoaderCallbacks i przekazać kontekst tak jak ten lm.initLoader(0, null, geocoderLoaderCallbacks(this))?

Jest podobne pytanie tutaj LoaderManager with multiple loaders: how to get the right cursorloader, ale nie wyjaśnia ono sposobu zarządzania dwoma ładowarkami o różnych typach danych.

Odpowiedz

9

Zawsze jest dobrze, aby przenieść kod z potencjalnie gigantycznej klasy i jest o wiele czystszy, aby zrobić to z różnymi klasami, niż z tymi, które mogą obsłużyć wszystko. Możesz nawet chcieć uczynić je prawdziwymi klasami zewnętrznymi zamiast klasami wewnętrznymi, jeśli uważasz, że Twoja Aktywność ma za dużo kodu wewnątrz. LoaderCallbacks to interfejs, dzięki któremu można go w większości wdrożyć w swojej klasie.

Przekazywanie Context w konstruktorze jest w porządku, o ile nie zachowujesz statycznych lub w inny sposób zapisanych w pamięci podręcznej odwołań do niego.

+1

Nie jestem pewien, czy "zachowuję statyczne lub w inny sposób buforowane odniesienia do niego". Kontekst jest potrzebny, ponieważ AsyncTaskLoader go potrzebuje. Muszę więc przekazać go do GeocoderLoaderCallbacks. Ale czy powinienem utworzyć go w mojej działalności i podać odniesienie do tego konkretnego działania? Czy nie wyciekłoby z działalności? We wszystkich przykładowych implementacjach (gdzie Activity implementuje LoaderCallbacks) używają one 'lm.initLoader (0, null, this);' ('this') do przekazania referencji do działania. Następnie jest automagicznie obsługiwany przez AsyncTaskLoader. Ale czy działa tak samo w przypadku statycznej klasy wewnętrznej? –

+1

Robiąc to w innej klasie i przechodząc do 'Kontekstu 'jest bezpieczny w odniesieniu do wycieków, ponieważ długość życia klasy wywołania zwrotnego jest powiązana z czasem życia samej czynności. Gdy działanie zostanie usunięte z pamięci, będą również wyświetlane wszystkie odnośniki wychodzące z tego miejsca. Jedyne, czego nie wolno ci robić, to używać zmiennych 'statycznych', które mają pewien rodzaj odniesienia do twojej Aktywności. Zwykle nie dostaniesz problemów z przeciekami, jeśli użyjesz podanych klas zgodnie z przeznaczeniem. – zapl

+0

Świetnie, dzięki! I +1 za wspominanie, aby nie używać zmiennych statycznych w odniesieniu do działania –

Powiązane problemy