2011-08-22 13 views
6

Tengo un par de problemas con AsyncTaskLoader, no estoy seguro de si están relacionados ya que ambos ocurren al intentar reiniciar el cargador. En mi aplicación tengo 3 instancias de un CursorAdapter personalizado, respaldado por 3 instancias de un AsyncTaskLoader personalizado administrado por 1 Singleton LoaderManager. Los problemas se relacionan con dos pares adaptador/cargador differenct, pero el código utilizado es el mismo en cada caso:Problema con las devoluciones de llamada AsyncTaskLoader personalizadas

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

Problema 1: llamo restartLoader() y el LoaderManager registra una llamada a onCreateLoader, pero no uno para onLoaderReset(). El cargador llega a deliverResult(), pero onLoadFinished() nunca se llama. El cargador no tiene configurados los indicadores 'restablecer' o 'iniciado' (ver código a continuación).

Problema 2: llamo a restartLoader() y el LoaderManager registra una llamada a onLoaderReset(). El cargador llega a onReset(), pero no avanza más. El Cursor está configurado como nulo, pero no se carga ningún Cursor nuevo.

¿Alguna idea de lo que podría ser el problema? He aquí algunos de los códigos para el Administrador de Cargador y cargador:

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

Respuesta

1

Lo que está llamando un 'LoaderManager' es en realidad una implementación de la interfaz LoaderManager.LoaderCallbacks<D>. Es posible que desee utilizar un nombre diferente, este es confuso. ¿Por qué es un singleton? Por lo general, está vinculado a una Actividad o Fragmento, posiblemente solo la Actividad/Fragmento que implementa la interfaz. ¿Dónde estás creando tus cargadores (actividad/fragmento)? Además, asegúrese de llamar al LoaderManager.initLoader() desde onCreate()/onActivityCreated(), de lo contrario, es posible que el cargador no se inicie correctamente.

+0

1. Sí, sé que el nombre no está claro, lo siento. 2. Ya no es un singleton - he estado trabajando en esa parte 3. El principal problema que tengo es que me gustaría poder usar el mismo Cursor con el mismo cargador en diferentes fragmentos vinculados a diferentes actividades – Pikaling

+0

¿Por qué? ¿quieres compartir cursores? Probablemente no sea una buena idea: los cargadores son gestionados por actividades/fragmentos, por lo que su cargador puede cerrarse cuando finalice otra actividad. Sin embargo, puede usar el mismo Loader _class_ y hacer que se cree una instancia en diferentes actividades/fragmentos. –

+0

Gracias por su ayuda. Revisé y volví a trabajar todo mi código, todo funcionaba ahora. A veces odio OOP ... – Pikaling

0

Cuando se crea un cursor y el punto de que en una base de datos, no puedo simplemente configurarlo como nulo. Tiene que cerrar explícitamente el cursor, o bloqueará la base de datos hasta que agote el tiempo de espera.

Recomiendo aprovechar el ciclo de vida de Android y sus devoluciones de llamada existentes para implementar esta solución.

Espero que esto ayude!

+0

Buena captura - eso debería ser changeCursor() no swapCursor() - He cambiado eso ahora – Pikaling

+0

¿sigues teniendo los mismos problemas? – Codeman

+0

¡No, intenté arreglarlo y lo empeoré! Siempre el camino ... – Pikaling

Cuestiones relacionadas