Me encuentro con una IllegalStateException actualizando una Lista subyacente a un Adaptador (podría ser un ArrayAdapter o una extensión de BaseAdapter, no lo recuerdo). No tengo ni recuerdo el texto de la excepción en este momento, pero dice algo sobre el cambio del contenido de la Lista sin que se haya notificado el cambio al Adaptador.¿Cuál es la mejor manera de actualizar los datos subyacentes de un adaptador?
Esta lista/puede/ser actualizada a partir de otro hilo que no sea el de la interfaz de usuario (principal). Después de actualizar esta lista (agregando un elemento), llamo notifyDataSetChanged. El problema parece ser que el Adaptador o ListView conectado al Adaptador intenta actualizarse antes de invocar este método. Cuando esto sucede, se lanza la IllegalStateException.
Si configuro la visibilidad de ListView en GONE antes de la actualización, entonces VISIBLE nuevamente, no se produce ningún error. Pero esto no siempre es práctico.
Leí en alguna parte que no se puede modificar el subyacente de otro hilo - esto parece limitar un patrón MVC, como con esta Lista en particular, quiero agregar elementos de diferentes hilos. Supuse que siempre que llamara notifyDataSetChanged() estaría seguro, que el Adaptador no revisó la Lista subyacente hasta que se invocó este método, pero este no parece ser el caso.
Supongo que lo que estoy preguntando es, ¿puede ser seguro actualizar la Lista subyacente de hilos que no sean la UI? Además, si deseo modificar los datos dentro de un Adaptador, ¿puedo modificar la Lista subyacente o el Adaptador mismo (a través de sus métodos add(), etc.)? La modificación de los datos a través del adaptador parece incorrecta.
Encontré un hilo en otro sitio de alguien que parece tener un problema similar al mío: http://osdir.com/ml/Android-Developers/2010-04/msg01199.html (esto es de donde tomé la idea Visibility.GONE y .VISIBLE).
Para darle una mejor idea de mi problema en particular, describiré un poco cómo mi Lista, Adaptador, etc. están configurados.
Tengo un objeto llamado Queue que contiene una LinkedList. Queue extiende Observable, y cuando las cosas se agregan a su lista interna a través de sus métodos, yo llamo a setChanged() y notifyListeners(). Este objeto Queue puede tener elementos agregados o eliminados de cualquier cantidad de subprocesos.
Tengo una única actividad "vista de cola" que contiene un adaptador. Esta actividad, en su método onCreate(), registra un escucha Observer en mi objeto Queue. En el método de actualización del Observador(), invoco notifyDataSetChanged() en el Adaptador.
Agregué una gran cantidad de salida de registro y determiné que cuando se produce esta IllegalStateExcption que mi Observer de devolución de llamada nunca fue invocada. De modo que es como si el Adaptador notara el cambio de la Lista antes de que el Observador tuviera la oportunidad de notificar a sus Observadores, y llama a mi método para notificar al Adaptador que el contenido había cambiado.
Supongo que lo que estoy preguntando es si esta es una buena forma de instalar un Adaptador. ¿Es esto un problema porque estoy actualizando el contenido del adaptador de un hilo que no sea el de la interfaz de usuario? Si este es el caso, puedo tener una solución en mente (darle al objeto Queue un Handler al hilo de UI cuando se crea, y hacer todas las modificaciones de List usando ese Handler, pero esto parece inapropiado).
Me doy cuenta de que esta es una publicación muy abierta, pero estoy un poco perdido en esto y agradecería cualquier comentario sobre lo que he escrito.
Gracias por sus comentarios, pero todavía estoy confundido en algunas cosas, si no le importa ayudar más. El nombre del objeto "Queue" es un poco inapropiado: es más una cola de medios de reproducción de videos o canciones para reproducir. Es una lista de elementos con un currentIndex int. Entendí que el Adaptador era solo un puente entre mi Modelo (mi Lista) y la vista (ListView). ¿Qué pasa si necesito actualizar los datos que muestra la vista desde otra actividad donde no tengo acceso al adaptador? Parecería natural actualizar la Lista subyacente, quizás desde un Runnable si la tarea que realiza este add pudiera bloquear. – skyler
"Entendí que el Adaptador era solo un puente entre mi Modelo (mi Lista) y la vista (ListView)." Eso es generalmente cierto. "¿Qué ocurre si necesito actualizar los datos que muestra la vista desde otra Actividad en la que no tengo acceso al Adaptador?" Lo más probable es que tampoco tengas acceso a la Lista, entonces necesitarás una estrategia más elaborada. "Parecería natural actualizar la Lista subyacente, tal vez desde un Runnable si la tarea que realiza este add pudiera bloquear". En mi humilde opinión, el problema de la rosca es un problema de IU, por lo que recomiendo que su adaptador sea el que se encargue de la seguridad de las roscas. – CommonsWare
Pero, puedes implementarlo como quieras, siempre y cuando solo actualices el Adaptador en el hilo principal de la aplicación. – CommonsWare