ejemplo - android loader example
Problemas con las devoluciones de llamada AsyncTaskLoader personalizadas (2)
Estoy teniendo un par de problemas con AsyncTaskLoader, no estoy seguro 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 diferentes de Adaptador / Loader, pero el código utilizado es el mismo en cada caso:
getLoaderManager().restartLoader(loaderId, bundle, loaderManager);
Problema 1: llamo a restartLoader () y el LoaderManager registra una llamada a onCreateLoader, pero no a 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 cual puede ser el problema? Aquí hay algunos códigos para el gestor de carga 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);
}
Cuando crea un cursor y lo apunta a una base de datos, no puede simplemente establecerlo en 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!
Lo que está llamando un ''LoaderManager'' es en realidad una implementación de la 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 a LoaderManager.initLoader()
desde onCreate()/onActivityCreated()
; de lo contrario, es posible que el cargador no se inicie correctamente.