2011-08-22 11 views
6

Sto riscontrando un paio di problemi con il mio AsyncTaskLoader, non sono sicuro che siano correlati in quanto entrambi si verificano quando si tenta di riavviare il Loader. Nella mia applicazione ho 3 istanze di un CursorAdapter personalizzato, supportato da 3 istanze di un AsyncTaskLoader personalizzato gestito da 1 singleton LoaderManager. I problemi riguardano due coppie adattatore/caricatore differenct, ma il codice utilizzato è la stessa in ogni caso:Problemi con i callback personalizzati AsyncTaskLoader

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

Problema 1: chiamo restartLoader() e la LoaderManager registri una chiamata a onCreateLoader, ma non uno di onLoaderReset(). Il programma di caricamento ottiene deliverResult(), ma onLoadFinished() non viene mai chiamato. Il Loader non ha né i flag 'reset' o 'started' impostati (vedi il codice sotto).

Problema 2: chiamo restartLoader() e LoaderManager registra una chiamata a onLoaderReset(). Il Loader arriva a onReset(), ma non ottiene altro. Il cursore è impostato su null, ma non viene caricato alcun nuovo cursore.

Qualche idea su quale potrebbe essere il problema? Ecco parte del codice per il Loader e Loader Responsabile:

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

risposta

1

Quello che si chiama "LoaderManager" è in realtà un'implementazione dell'interfaccia LoaderManager.LoaderCallbacks<D>. Potresti voler usare un nome diverso, questo è confuso. Perché è un singleton? Solitamente è legato a un'attività o a un frammento, forse solo all'attività/frammento che implementa l'interfaccia. Dove stai creando i tuoi Loader (attività/frammento)? Assicurati inoltre di chiamare LoaderManager.initLoader() da onCreate()/onActivityCreated(), altrimenti il ​​caricatore potrebbe non essere avviato correttamente.

+0

1. Sì, so che il nome non è chiaro, mi dispiace. 2. Non è più un singleton - ho lavorato su quella parte 3. Il problema principale che sto avendo è che mi piacerebbe essere in grado di usare lo stesso cursore con lo stesso caricatore in diversi frammenti legati a diverse attività – Pikaling

+0

Perché vuoi condividere i cursori? Probabilmente non è una buona idea: i caricatori sono gestiti da attività/frammenti, quindi il tuo caricatore potrebbe essere chiuso quando termina un'altra attività. Puoi usare lo stesso Loader _class_ e farlo istanziare in diverse attività/frammenti. –

+0

Grazie per il vostro aiuto. Ho esaminato e rielaborato tutto il mio codice, tutto funzionante ora. A volte odio OOP ... – Pikaling

0

Quando si crea un cursore e puntarlo verso un database, è non può semplicemente impostarlo su null. Devi chiudere esplicitamente il cursore, altrimenti bloccherà il database finché non scade.

Si consiglia di sfruttare il ciclo di vita di Android e i callback esistenti per implementare questa correzione.

Spero che questo aiuti!

+0

Buona cattura - che dovrebbe essere cambiaCursore() non swapCursor() - Ho cambiato che ora – Pikaling

+0

hai ancora gli stessi problemi? – Codeman

+0

No, ho provato a ripararlo e ho peggiorato le cose! Sempre il modo ... – Pikaling

Problemi correlati