2012-04-11 12 views
6

Quiero saber cómo usar el CursorLoader para rellenar los widgets en una pantalla. Todos los ejemplos en línea son solo para usar un adaptador y esto funciona muy bien. Lo que necesito es una forma confiable de actualizar las vistas en mi pantalla desde un Cursor y en el hilo de UI y sin que a veces se cuelgue debido a StaleDataException o que el cursor se desactive de repente. Este es mi enfoque actual, pero aún recibo algunos informes de fallas de los usuarios.Rellenar widgets desde un cursor en onLoadFinished()

@Override 
    public Loader<Cursor> onCreateLoader(int id, Bundle arg1) { 
     CursorLoader loader = null; 

     switch (id) { 
      case LOADER_ID_DATA: 
       loader = new CursorLoader(...); 
       break; 
     } 

     return loader; 
    } 

    @Override 
    public void onLoadFinished(Loader<Cursor> loader, final Cursor cursor) { 
     handler.post(new Runnable() { 

      @Override 
      public void run() { 
       if (getActivity() == null) 
        return; 

       updateView(cursor); 
      } 
     }); 
    } 

    @Override 
    public void onLoaderReset(Loader<Cursor> arg0) { 
    } 

Una solución sería la de recuperar todos los campos del cursor directamente en el interior onLoadFinished y pasar a todos al controlador para rellenar los widgets en el hilo de interfaz de usuario. Pero esto es feo porque puedo tener muchos valores en el cursor. Me encantaría encontrar una forma confiable y sin complicaciones de lidiar con todo esto.

+0

"Una solución sería recuperar todos los campos del cursor directamente dentro de OnLoadFinished y pasarlos al manejador para rellenar los widgets en el subproceso de UI" - se invoca 'onLoadFinished()' en el subproceso principal de la aplicación. – CommonsWare

+0

@CommonsWare Hasta donde yo sé, onLoadFinished no se llama en el hilo principal de UI. Si busca, por ejemplo, en el código fuente android-protips_location escrito por Reto Meier, utiliza un controlador para rellenar los widgets con los valores. Y su comentario anterior en LoadFinished() es que programa una actualización en el hilo principal de la aplicación. –

+0

Cita de Reto Meier: "Tenga en cuenta que onLoadFinished no está sincronizado con el subproceso principal de la aplicación, entonces estoy extrayendo los valores del Cursor en el mismo subproceso cuando se cargó el Cursor, antes de publicar un Runnable nuevo en el subproceso de UI que asigna los nuevos valores a los elementos de la interfaz de usuario " –

Respuesta

7

Después de preguntar sobre # android-dev SimonVT y readme, me ayudó a llegar al fondo de esto.

No hay nada que indique que onLoadFinished será invocado en el hilo de la interfaz de usuario así que en teoría debería usar un Handler como se aconseja en el libro de Reto. Sin embargo, cuando se utiliza un CursorLoader (que es, con mucho, el caso de uso más común), se puede garantizar que onLoadFinished se llamará en el hilo de la interfaz de usuario.

+3

El motivo de "bastante" es que CursorLoader utiliza una AsyncTask para hacer su trabajo en segundo plano, que utiliza un controlador estático para publicar de nuevo, y finalmente llama a onLoadFinished. Si llama a LoaderManager.initLoader (...) desde el hilo principal, se garantiza que el controlador también se adjuntará al hilo principal. Para que este manejador no esté unido al hilo principal, deberá crear un hilo con un Looper e iniciar el cargador desde allí. – SimonVT

Cuestiones relacionadas