2011-08-22 22 views
6

Mam kilka problemów z moim AsyncTaskLoader, nie jestem pewien, czy są one powiązane, jak to się dzieje podczas próby ponownego uruchomienia programu ładującego. W mojej aplikacji mam 3 wystąpienia niestandardowego CursorAdapter, wspierane przez 3 wystąpienia niestandardowego AsyncTaskLoader zarządzanego przez 1 singleton LoaderManager. Problemy dotyczą dwóch differenct par Adapter/Ładowarka, ale kod jest taka sama w każdym przypadku:Problemy z niestandardowymi wywołaniami AsyncTaskLoader

getLoaderManager().restartLoader(loaderId, bundle, loaderManager); 

Problem 1: Wzywam restartLoader() i LoaderManager rejestruje wywołanie onCreateLoader, ale nie jeden onLoaderReset(). Program ładujący dostaje metodę dostarczaniaResult(), ale funkcja onLoadFinished() nigdy nie jest wywoływana. Moduł ładujący nie ma ustawionych flag "reset" ani "uruchomionych" (patrz kod poniżej).

Problem 2: Wzywam restartLoader(), a LoaderManager rejestruje wywołanie onLoaderReset(). Program ładujący dostaje onReReset(), ale nie robi nic więcej. Kursor ma wartość NULL, ale nie załadowano nowego kursora.

Jakieś pomysły na temat problemu? Oto niektóre z kodu dla Loader i Loader Manager:

CustomCursorLoader.java

@Override 
protected void onStartLoading() { 
    Log.v(TAG, "Starting Loader"); 
    if (lastCursor != null) { 
     deliverResult(lastCursor); 
    } 
    if (takeContentChanged() || lastCursor == null) { 
     forceLoad(); 
    } 
} 

@Override 
public void deliverResult(Cursor cursor) { 
    Log.v(TAG, "Delivering result"); 
    if (isReset()) { 
     Log.v(TAG, "reset"); 
     if (cursor != null) { 
      cursor.close(); 
     } 
     return; 
    } 
    Cursor oldCursor = lastCursor; 
    lastCursor = cursor; 
    if (isStarted()) { 
     Log.v(TAG, "started"); 
     super.deliverResult(cursor); 
    } 
    if (oldCursor != null && oldCursor != cursor && !oldCursor.isClosed()) { 
     oldCursor.close(); 
    } 
} 

@Override 
protected void onReset() { 
    Log.v(TAG, "Reset"); 
    super.onReset(); 
    onStopLoading(); 
    if (lastCursor != null && !lastCursor.isClosed()) { 
     lastCursor.close(); 
    } 
    lastCursor = null; 
} 

CustomCursorLoaderManager.java:

@Override 
public Loader<Cursor> onCreateLoader(int loaderId, Bundle bundle) { 
    return new CustomCursorLoader(); 
} 

@Override 
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) { 
    cursorAdapter.changeCursor(cursor); 
} 

@Override 
public void onLoaderReset(Loader<Cursor> loader) { 
    cursorAdapter.changeCursor(null); 
} 

Odpowiedz

1

To, co nazywasz "LoaderManager", jest w rzeczywistości implementacją interfejsu LoaderManager.LoaderCallbacks<D>. Możesz użyć innej nazwy, ta jest myląca. Dlaczego to singleton? Zwykle jest związany z działaniem lub fragmentem, prawdopodobnie tylko z działaniem/fragmentem implementującym interfejs. Gdzie tworzysz swoje ładowarki (aktywność/fragment)? Upewnij się również, że dzwonisz pod numer LoaderManager.initLoader() z onCreate()/onActivityCreated(), w przeciwnym razie program ładujący może nie zostać poprawnie uruchomiony.

+0

1. Tak, wiem, że nazwisko nie jest jasne, przepraszam. 2. To już nie singleton - pracowałem nad tą częścią 3. Głównym problemem, jaki mam, jest możliwość użycia tego samego kursora z tym samym modułem ładującym w różnych fragmentach powiązanych z różnymi działaniami. – Pikaling

+0

Dlaczego czy chcesz udostępniać kursory? To prawdopodobnie nie jest dobry pomysł: ładowarki są zarządzane przez działania/fragmenty, więc twój program ładujący może być zamknięty, gdy kończy się inne działanie. Możesz użyć tego samego programu ładującego _class_ i mieć jego instancję w różnych działaniach/fragmentach. –

+0

Dzięki za pomoc. Przeszedłem i przerobiłem cały mój kod, wszystkie teraz działają. Czasami nienawidzę OOP ... – Pikaling

0

Podczas tworzenia kursor i skierować go w bazie danych, nie może po prostu ustawić go na wartość null. Musisz wyraźnie zamknąć kursor lub zablokuje bazę danych, dopóki nie przekroczy limitu czasu.

Zalecam korzystanie z cyklu życia systemu Android i istniejących połączeń zwrotnych w celu wdrożenia tej poprawki.

Mam nadzieję, że to pomoże!

+0

Dobry połów - to powinno być changeCursor(), a nie swapCursor() - Zmieniłem to teraz – Pikaling

+0

czy wciąż masz te same problemy? – Codeman

+0

Nie Próbowałem go naprawić i pogorszyłem! Zawsze tak ... – Pikaling

Powiązane problemy