android - loadercallbacks - ¿Cómo sabe CursorLoader con LoaderManager para enviar el cursor a un CursorAdapter?
android-contentprovider android-loadermanager (1)
En primer lugar, eche un vistazo al ejemplo de código en esta publicación y en esta publicación para obtener información más detallada sobre cómo funciona el proceso.
Y ahora, para responder a tus preguntas ...
¿Cómo funciona el método query () de mi
ContentProvider
personalizado ...?
Bueno, primero recuerde que getContentResolver().query()
no invoca el método de query
del proveedor de contenido directamente. Está invocando el método de consulta del resolutor de contenido, que analiza el Uri
, determina el proveedor que desea invocar y luego llama al método de query
su proveedor .
¿Cómo se envía la consulta a ese
CursorAdapter
específico?
Le guiaré a través del proceso utilizando las Demos de API como ejemplo. Tenga en cuenta que las demostraciones de API utilizan un ListFragment
lugar de un ListActivity
(la diferencia no es importante en el contexto de esta pregunta).
Primero, cree (y configure) el
CursorAdapter
.mAdapter = new SimpleCursorAdapter( getActivity(), android.R.layout.simple_list_item_2, null, new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS }, new int[] { android.R.id.text1, android.R.id.text2 }, 0);
Una vez que se ejecuta esta instrucción,
SimpleCursorAdapter
sabe cómo debe asociar los datos del cursor con sus vistas. Los datos que se encuentren en la columnaContacts.DISPLAY_NAME
del cursor se asociarán a la vista con el IDandroid.R.id.text1
, etc.Tenga en cuenta que ha pasado un cursor
null
como el tercer argumento al constructor. Esto es muy importante , ya que todavía no hemos consultado ningún dato (este es el trabajo deLoaderManager
yCursorLoader
).A continuación, inicialice el cargador.
getLoaderManager().initLoader(0, null, this);
Esto le indica al
LoaderManager
que cree e inicie elLoader
correspondiente a id0
.El
LoaderManager
llamaonCreateLoader(int id, Bundle args)
.onCreateloader
devuelve una subclase de la interfaz delLoader<Cursor>
(es decir, unCursorLoader
, en este caso). EsteCursorLoader
realizará la consulta inicial y se actualizará cuando cambien los datos.Si su actividad / fragmento tiene más de un cargador, entonces usaría
switch(id)
para determinar el cargador específico que ha recibido instrucciones para comenzar el proceso de carga.El cursor consultado se pasa a
onLoadFinished()
.Inmediatamente después de que
CursorLoader
seCursorLoader
una instancia y se devuelve en el paso 3,CursorLoader
realiza la consulta inicial en un subproceso independiente y se devuelve un cursor. CuandoCursorLoader
finaliza la consulta, devuelve el cursor recién consultado alLoaderManager
, que luego pasa el cursor al métodoonLoadFinished
. Desde la documentación, "el métodoonLoadFinished
se llama cuando un cargador creado previamente ha finalizado su carga".Los datos consultados están asociados con el
CursorAdapter
.mAdapter.swapCursor(data);
Tenga en cuenta que
onLoadFinished
también suele ser donde se actualiza la IU de la actividad / fragmento con los datos consultados. Esto no es necesario en este caso, como hemos llamado anteriormentesetListAdapter(mAdapter)
.ListFragment
sabe cómo usar elCursorAdapter
(vea el paso 1) ... todo lo que tenemos que hacer es pasarle el cursor al adaptador conswapCursor
, yListFragment
se encargará deListFragment
los datos en la pantalla.
Avíseme si tiene alguna pregunta (o si hay errores tipográficos, etc.).
TL; DR
El cursor que contiene sus datos consultados está asociado con el CursorAdapter
en onLoadFinished
. Esto se hace normalmente llamando a mAdapter.swapCursor(data)
.
Estaba revisando parte de mi código y me di cuenta de que en realidad no sé cómo se utiliza una combinación de CursorLoader
y LoaderManager
con un CursorAdapter
. Aquí está la parte en la que estoy confundido.
agendaAdapter = new MyAgendaAdapter(this, null);
makeProviderBundle(new String[] {"_id", "event_name", "start_date", "start_time",
"end_date", "end_time", "location"}, "date(?) >= start_date and date(?) <= end_date",
new String[]{getChosenDate(), getChosenDate()}, null);
getLoaderManager().initLoader(0, myBundle, MainDisplayActivity.this);
list.setAdapter(agendaAdapter);
Entonces, ¿cómo sabe el método query()
de mi ContentProvider
personalizado para enviarlo a ese CursorAdapter
específico? Simplemente no veo la conexión. Entiendo todo lo demás en eso, pero en qué consiste esta pregunta. Ah, y debo mencionar, el código funciona bien.