Tengo un ContentProvider
personalizado que gestiona el acceso a una base de datos SQLite. Para cargar el contenido de una tabla de base de datos en un ListFragment
, utilizo el LoaderManager
con un CursorLoader
y una CursorAdapter
:Android ContentProvider llama ráfagas de setNotificationUri() a CursorAdapter cuando se insertan muchas filas con una operación por lotes
public class MyListFragment extends ListFragment implements LoaderCallbacks<Cursor> {
// ...
CursorAdapter mAdapter;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mAdapter = new CursorAdapter(getActivity(), null, 0);
setListAdapter(mAdapter);
getLoaderManager().initLoader(LOADER_ID, null, this);
}
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity(), CONTENT_URI, PROJECTION, null, null, null);
}
public void onLoadFinished(Loader<Cursor> loader, Cursor c) {
mAdapter.swapCursor(c);
}
public void onLoaderReset(Loader<Cursor> loader) {
mAdapter.swapCursor(null);
}
}
La base de datos SQLite se actualiza mediante una tarea de fondo, que se vende a un número de elementos de un servicio web y inserta estos elementos en la base de datos a través de ContentProvider
operaciones por lotes (ContentResolver#applyBatch()
).
Incluso si se trata de una operación por lotes, ContentProvider#insert()
invocan por cada fila se inserta en la base de datos y, en la implementación actual, las llamadas ContentProvider
setNotificationUri()
para cada comando de inserción.
El resultado es que el CursorAdapter
recibe ráfagas de notificaciones, lo que hace que la interfaz de usuario se actualice con demasiada frecuencia con el consiguiente efecto de parpadeo molesto.
Idealmente, cuando una operación por lotes está en progreso, debería haber una manera de notificar ContentObserver
solo al final de cualquier operación por lotes y no con cada comando de inserción.
¿Alguien sabe si esto es posible? Tenga en cuenta que puedo cambiar la implementación de ContentProvider
y anular cualquiera de sus métodos.
Considere hacer/basar su proveedor en algo como [SQLiteContentProvider] (http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android-apps/2.2_r1.1 /com/android/providers/calendar/SQLiteContentProvider.java/?v=source): proporciona muchos de los fundamentos de un proveedor agradable y funcional basado en SQLite, y si lo hace, simplemente debe usar bulkInsert o applyBatch para hacer tus "inserciones masivas". El beneficio adicional es que sus inserciones masivas se realizarán en una transacción que les acelera bastante. – Jens
@Jens muchas gracias por el puntero, esto parece exactamente lo que estaba buscando. Solo una pregunta al respecto: ¿quién ha desarrollado y publicado este código? Desde el encabezado, parece ser parte del Proyecto de Código Abierto de Android, pero, si este es el caso, ¿por qué Google no lo ha lanzado con el SDK estándar de Android? –
Es parte del proyecto AOSP pero no está publicado en el SDK, por lo que no sé, ya que incluirlo hubiera evitado que mucha gente escribiera sus propias implementaciones 'ContentProvider'. – Jens