2010-09-27 21 views
5

Tengo una lista bastante simple con 3 campos textview en cada fila. Estamos actualizando sus valores cada 2 segundos más o menos con los datos procedentes de una llamada fondo de servicio web (AsyncTask)Listview's ArrayAdapter notifydatasetchanged() muy lento redraw

Comparamos los valores que vienen con los actuales, actualizar en consecuencia en el adaptador y, finalmente, llamando notifyDataSetChanged() si es necesario

Lo que pasa es que el redibujado se vuelve realmente lento y cuelga toda la interfaz de usuario cuando recibimos más de 3 filas de actualización a la vez. Por supuesto, estamos utilizando todas las optimizaciones conocidas de ListView, como el enfoque EfficientAdapter (setTag() y titulares) y getViewTypecount()/getItemViewType(). También hemos intentado optimizar nuestra interfaz tanto como sea posible con layoutopt y tratando de evitar el ancho y la altura de wrap_content para aligerar las cosas.

Tampoco realizamos operaciones caras en nuestras actualizaciones, solo elementos estándar: cambio de texto de TextView, textcolor y valores de color de fondo.

Lo único raro que puedo ver es que getView() se llama 3-4-5 veces para cada fila, a pesar de que he leído todos los mensajes de los Romain [1] dice que no es nada malo en ello

¿Alguna idea o sugerencia sobre cómo podemos acelerarla?

¡Muchas gracias!

[1] http://groups.google.com/group/android-developers/browse_thread/thread/4c4aedde22fe4594/aeb04288064f495e?show_docid=aeb04288064f495e

+0

Parece que recibe más actualizaciones de las que puede dibujar: ¿ha intentado reducir la frecuencia de las actualizaciones a 10 segundos para probar esto? Si esto ayuda, deberá encontrar una solución para borrar la cola de la tarea con cada actualización. 2 segundos es bastante frecuente si considera que la recolección automática de basura puede tomar hasta 1 segundo (ojalá no más) y otros servicios pueden retrasar la actualización también. –

+0

Las llamadas son consecutivas, por lo que las nuevas se ejecutan cuando la anterior ha finalizado. – Albert

+0

El peor caso del recolector de basura lleva más de 200 ms, eso no es nada en comparación con el bloqueo de la IU de 1,5 a 2 que la aplicación experimenta en cada redibujado. La frecuencia de actualización no está afectando aquí, incluso si la elevo a 10s, después de que se activa la llamada, el redibujado continuará congelando durante esos 2 segundos – Albert

Respuesta

0

supongo que se puede establecer una etiqueta para ur Textview como la url donde obtendrá la actualización desde. Y en lugar de llamar a "notifyDataSetChanged()", puede intentar usar findViewByTag (actualización de URL) y setText para esa vista, por lo que la vista de texto solo se repinta, no la lista completa una y otra vez. Reduciría suficientemente la cantidad de repintados adicionales. Solo un pensamiento.

1

Esto es para aquellos que navegan desde Google pensando que necesitan reescribir su propio método de cambio de datos. Según mis datos, no es necesario para muchos casos.

notifyDataSetChanged() puede ser MUCHO MÁS RÁPIDO que su reemplazo codificado a mano y todo depende de su implementación real listview.

Ejemplo: una simple lista de tres líneas solo texto con 10K fila máxima ArrayList actualizada a través de la selección del menú.

Manual notifyDataSetChange()

--- avg run-time: 4ms 

defecto libre notifyDataSetChange()

--- avg run-time: 0ms <--- you can't get faster than this. 

No ejecutar para crear su propio reemplazo a menos que el tiempo y comparar su material. Use las cosas gratis hasta que sea necesario.