¿Cómo programar un trabajo pesado para su posterior visualización para listas?

Tengo un listview con 200 artículos. Utilizo una vista personalizada para cada fila. Hay un código que toma un cierto tiempo para calcular, y debido a esto la lista cuelga hacia fuera en el desplazamiento y cargas en lento (2-3sec).

He subclasificado SimpleCursorAdapter, y usando Filterable y SectionIndexer.

Tengo en mente para mostrar inicialmente el nombre del registro, y poner en un hilo el cálculo, y se mostrará más tarde cuando se hace.

¿Cómo puedo retroceder un poco de trabajo y, más tarde, actualizar el listview para incluir los datos calculados? Esto debería aparecer en vuelo sin la interacción del usuario.

Desde android la interfaz de usuario de Android es singlethreaded se bloqueará cada vez que realice una operación larga.

Usted podría hacer el roscado java regular y tener un Handler () en la clase de interfaz de usuario principal en la que puede alimentar la información. Pero..

La forma más sencilla sería crear un AsyncTask (). Son hilos de java con un ligero cambio. Pueden realizar una operación de interfaz de usuario antes / después del cálculo principal. Así por ejemplo:

private class AndroidThread extends AsyncTask { protected Object doInBackground(Object... params) { return result; } protected void onPostExecute(Object result) { // do things here with the result of the doInBackground function // Like: "UiElement"."performTask(result)" } } 

Para más información sobre AsyncTask, vea esto

Hmm, pregunta interesante. Aquí hay algunas ideas rápidas:

1) Ponga los valores que se pueden recuperar directamente, es decir, el nombre del registro tal y como lo coloca, directamente en la lista. Deje valores predeterminados, como "Cargar …", para todo lo que puede tardar un tiempo en calcular.

2) Crear un segundo hilo para hacer los cálculos, pero para asegurarse de que no se calcula todo utilizar ListView's onScrollStateChanged oyentes. Esto le permite hacer sólo el trabajo de fondo cuando la lista está inactiva, o desplazarse lentamente mediante el desplazamiento táctil. En otras palabras, no te molestes cuando esté en modo 'fling' ya que las filas pasarán mucho antes de que los cálculos terminen.

3) No estoy completamente seguro de cómo se puede enqueue la etapa de carga en el hilo. Sólo desea tener un hilo de carga – abrir un nuevo hilo para cada fila sería bastante desordenado y también inútil como los teléfonos no son multicore – pero eso significa que el hilo tiene que tener un sistema de colas. Lo que quiero decir es que el hilo tiene que ser consciente de qué filas están esperando para el cálculo, pero no he pensado en cómo lo haría todavía. Sin embargo, esto también tendría que estar vinculado a qué filas son visibles. No hay ningún punto en el hilo de cálculo de la información de las filas de largo pasado en la lista.

4) Siempre que el hilo de carga termine una fila en particular, podría llamar a notifyDatasetChanged () en el adaptador de lista. Esto puede ser un poco pesado si el ListView intenta actualizar sus datos para cada fila en lugar de sólo los visibles, pero tendría que experimentar para ver.

Espero que estas ideas ayuden un poco!


En respuesta al comentario: Suponiendo que está preguntando cuándo una fila está visible, puede hacerlo implementando ListView.OnScrollListener. Tomé inspiración de ApiDemos List13, pero aquí están los bits de código relevantes:

 public class YourClass extends ListActivity implements ListView.OnScrollListener { public void onCreate(Bundle sIS){ (...) // Note, you may have to write your own list adapter, extending BaseAdapter // See List13 in Api Demos for an example if you're not sure how to do that setListAdapter(yourImageAdapter); getListView().setOnScrollListener(this); } public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { Log.d(LOG_TAG, "onScroll, firstVisibleItem = " + firstVisibleItem + ", visibleItemCount = " + visibleItemCount + ", totalItemCount = " + totalItemCount); } public void onScrollStateChanged(AbsListView view, int scrollState) { Log.d(LOG_TAG, "onScrollStateChanged called, scrollState = " + scrollState); switch (scrollState) { case OnScrollListener.SCROLL_STATE_IDLE: int first = view.getFirstVisiblePosition(); int count = view.getChildCount(); Log.d(LOG_TAG, "first = " + first + ", count = " + count); break; case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL: //Scrolling with the finger touching the screen break; case OnScrollListener.SCROLL_STATE_FLING: // User 'threw' the list up or down and it's scrolling rapidly break; } } } 

Eso te dice todo acerca de tu lista: si se trata de desplazamiento, qué es visible, etc. Si usas eso con el hilo de carga para hacer sólo el trabajo de fondo para las filas visibles, eso debería ayudar a reducir la sobrecarga innecesaria.

Otro punto sobre BaseAdapter: No he intentado usar ninguna otra forma de adaptador de lista, así que tal vez sea lo mismo con todos ellos, pero una cosa muy útil con BaseAdapter es que te permite manejar la "inflación" de cada fila individualmente. Cada vez que la lista está a punto de mostrar una nueva fila, getView se llama. Usted puede poner el código personalizado allí para hacer cosas como poner "Cargando …" si la información aún no se ha calculado, o realmente mostrarlo si tiene.

Por cierto, ¿qué estás calculando realmente en esta lista que toma tanto tiempo?

  • Androide modificar el texto EditarTexto
  • Espere a que se complete el AsyncTask múltiple
  • ¿Cómo ejecutar una función cada dos segundos en Java en Android?
  • Cómo matar un hilo y un controlador antes de ir a una nueva actividad
  • Cómo llamar a las actividades de un hilo no actividad?
  • ¿Cómo puedo implementar un Timer / TimerTask que ejecuta un AsyncTask? (Androide)
  • Multithreading en Android
  • SYSTEM_UI_FLAG_LOW_PROFILE no se puede resolver o no es un campo para google threadsample
  • AsyncTask para actualizar widget - cómo acceder a textviews en onPostExecute ()?
  • Cargar anuncio (adMob) en el subproceso de fondo
  • Implementación de un grupo de subprocesos dentro de un servicio
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.