loadercallbacks android android-contentprovider android-loadermanager android-cursorloader

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).

  1. 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 columna Contacts.DISPLAY_NAME del cursor se asociarán a la vista con el ID android.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 de LoaderManager y CursorLoader ).

  2. A continuación, inicialice el cargador.

    getLoaderManager().initLoader(0, null, this);

    Esto le indica al LoaderManager que cree e inicie el Loader correspondiente a id 0 .

  3. El LoaderManager llama onCreateLoader(int id, Bundle args) .

    onCreateloader devuelve una subclase de la interfaz del Loader<Cursor> (es decir, un CursorLoader , en este caso). Este CursorLoader 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.

  4. El cursor consultado se pasa a onLoadFinished() .

    Inmediatamente después de que CursorLoader se CursorLoader una instancia y se devuelve en el paso 3, CursorLoader realiza la consulta inicial en un subproceso independiente y se devuelve un cursor. Cuando CursorLoader finaliza la consulta, devuelve el cursor recién consultado al LoaderManager , que luego pasa el cursor al método onLoadFinished . Desde la documentación, "el método onLoadFinished se llama cuando un cargador creado previamente ha finalizado su carga".

  5. 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 anteriormente setListAdapter(mAdapter) . ListFragment sabe cómo usar el CursorAdapter (vea el paso 1) ... todo lo que tenemos que hacer es pasarle el cursor al adaptador con swapCursor , y ListFragment se encargará de ListFragment 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.