¿Cómo sabe CursorLoader con LoaderManager enviar el cursor a un CursorAdapter?


Estaba revisando parte de mi código y me di cuenta de que en realidad no sé cómo una combinación CursorLoader y LoaderManager se usa con una conexión 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 enviarlo a ese CursorAdapter específico? No veo la conexión. Entiendo todo lo demás en eso, pero en qué consiste esta pregunta. Y debo mencionar que el código funciona bien.

Author: Alex Lockwood, 2012-06-22

1 answers

En primer lugar, echa un vistazo a la muestra de código en este post y este post para una mirada aún más profunda sobre cómo funciona el proceso.

Y ahora, para responder a sus preguntas...

Cómo funciona el método query() desde mi personalizado ContentProvider...?

Bueno, primero recuerda que getContentResolver().query() no invoca el método query del proveedor de contenido directamente. Está invocando el método de consulta del solucionador de contenido, que analiza Uri, determina el proveedor desea invocar, y luego llama al método query de su proveedor.

¿Cómo se envía la consulta a ese CursorAdapter específico?

Te guiaré a través del proceso usando el Demostraciones de API como ejemplo. Tenga en cuenta que las demostraciones de la API utilizan un ListFragment en lugar de un ListActivity (la diferencia no es importante en el contexto de esta pregunta).


  1. Primero, crear (y configurar) 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);
    

    Después de ejecutar esta instrucción, el SimpleCursorAdapter sabe cómo debe asociar los datos del cursor con sus vistas. Cualquier dato que esté en la columna Contacts.DISPLAY_NAME del cursor se asociará con la vista con id android.R.id.text1, etc.

    Tenga en cuenta que ha pasado un cursor null como 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. Siguiente, inicializar el cargador.

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

    Esto le dice a LoaderManager que cree y comience el Loader correspondiente a id 0.

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

    onCreateloader devuelve una subclase de la interfaz Loader<Cursor> (es decir, a CursorLoader, en este caso). Este CursorLoader realizará la consulta inicial y se actualizará cuando los datos cambien.

    Si su actividad / fragmento tiene más de un cargador, entonces usaría switch(id) para determinar el cargador específico eso ha sido instruido para comenzar el proceso de carga.

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

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

  5. Los datos consultados están asociados con el CursorAdapter.

    mAdapter.swapCursor(data);
    

    Tenga en cuenta que onLoadFinished también es típicamente 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). El ListFragment sabe cómo usar el CursorAdapter (ver paso 1)... todo lo que necesitamos hacer es pasar el adaptador el cursor con swapCursor, y el ListFragment se encargará de mostrar los datos en la pantalla para nosotros.

Hágame saber si tiene alguna pregunta (o si hay algún error tipográfico, etc.).


TL; DR

El cursor que contiene los datos consultados está asociado con CursorAdapter en onLoadFinished. Esto se hace típicamente llamando a mAdapter.swapCursor(data).

 84
Author: Alex Lockwood,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-21 21:22:51