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
ContentProviderpersonalizado ...?
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
CursorAdapterespecí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,
SimpleCursorAdaptersabe cómo debe asociar los datos del cursor con sus vistas. Los datos que se encuentren en la columnaContacts.DISPLAY_NAMEdel cursor se asociarán a la vista con el IDandroid.R.id.text1, etc.Tenga en cuenta que ha pasado un cursor
nullcomo el tercer argumento al constructor. Esto es muy importante , ya que todavía no hemos consultado ningún dato (este es el trabajo deLoaderManageryCursorLoader).A continuación, inicialice el cargador.
getLoaderManager().initLoader(0, null, this);Esto le indica al
LoaderManagerque cree e inicie elLoadercorrespondiente a id0.El
LoaderManagerllamaonCreateLoader(int id, Bundle args).onCreateloaderdevuelve una subclase de la interfaz delLoader<Cursor>(es decir, unCursorLoader, en este caso). EsteCursorLoaderrealizará 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
CursorLoaderseCursorLoaderuna instancia y se devuelve en el paso 3,CursorLoaderrealiza la consulta inicial en un subproceso independiente y se devuelve un cursor. CuandoCursorLoaderfinaliza la consulta, devuelve el cursor recién consultado alLoaderManager, que luego pasa el cursor al métodoonLoadFinished. Desde la documentación, "el métodoonLoadFinishedse 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
onLoadFinishedtambié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).ListFragmentsabe cómo usar elCursorAdapter(vea el paso 1) ... todo lo que tenemos que hacer es pasarle el cursor al adaptador conswapCursor, yListFragmentse encargará deListFragmentlos 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.