Android ListView notifyDataSetChanged () de Service

Tengo un servicio del fondo que recibe mensajes de un servidor y con esos mensajes se actualiza las propiedades internas de los objetos que se muestran en un ListView.

Siempre utilizo el método runOnUiThread para ejecutar el comando listArrayAdapter.notifyOnDataSetChanged ().

Por alguna razón a veces el ListView se actualiza y me muestra la actualización de la propiedad y, a veces no.

Para las pruebas he añadido un botón de "actualización" a mi ListView y cuando se presiona el listArrayAdapter.notifyOnDataSetChanged () se ejecuta.

Cada clic en el botón de la vista se actualiza perfectamente ..

Realmente no puedo entender por qué al intentar actualizar desde el servicio que no siempre funciona, pero creo que tal vez no siempre se ejecuta en el UIThread …

Estoy realmente sin esperanza y me alegro de conseguir ayuda ..

Mi código

ServerConnectionManager.java – extiende el servicio

//example of a command executed when a specific message received from the server: //app is the Application variable public void unFriend(int userId) { serverResponseManager.onUnFriend(app.getApplicationFriend(userId),false); } 

ServerResponseManager.java – una clase que maneja todas las respuestas de la aplicación a los mensajes del servidor:

  public void onUnFriend(FacebookUser facebookUser, boolean isYouRemovedClient) { //this is the property which will effect the ListView view when calling the //arrayListAdataper.notifyOnDataSetChanged(); facebookUser.setApplicationFriend(false); app.getApplicationFriends().remove(facebookUser); app.getDatabaseManager().deleteApplicationFriend(facebookUser.getId()); //if the application is currently running in the UI (not on the background) it will run a method inside the BaseActivity if (app.isApplicationInForeground()) { app.getCurrentActivity().onUnFriend(facebookUser); if (isYouRemovedClient) app.showToast(facebookUser.getName() + " has removed from your friends", true); else app.showToast(facebookUser.getName() + " has removed you from friends", true); } } 

BaseActivity.java – una Actividad que establece toda la configuración predeterminada para todas las Actividades que lo extiende

 //in this exemple the BaseActivity method does nothing but the ListViewActivity.java method override it public void onUnFriend(FacebookUser facebookUser) { } 

ListViewActivity.java – extiende BaseActivity y tiene un ListView en él que debe reflejar el cambio en la propiedad de objeto de FacebookUser que se hace en public void onUnFriend (FacebookUser facebookUser, boolean isYouRemovedClient) en ServerResponseManager.

 @Override public void onUnFriend(FacebookUser facebookUser) { updateView(); } private void updateView() { runOnUiThread(updateViewRunnable()); } private Runnable updateViewRunnable() { Runnable run = new Runnable() { @Override public void run() { listArrayAdapter.notifyDataSetChanged(); } }; return run; } 

No mezcle la lógica del negocio. Parece tan complicado que es difícil de leer.

  1. En su servicio, difundir una intención con información sobre la actualización.
  2. En Activity donde está ListView , cree y registre BroadcastReceiver con IntentFilter para los eventos de actualización.
  3. En el método onReceive de sus eventos de actualización de identificador de BroadcastReceiver , por ejemplo, lista de actualizaciones.

Un Servicio normalmente debe ser independiente de las preocupaciones de la UI. Una gran manera de desacoplar servicios y cosas relacionadas con la interfaz de usuario es el patrón de bus de eventos. Para Android, consulta https://github.com/greenrobot/EventBus .

En ServerConnectionManager, puede publicar un evento:

 EventBus.getDefault().post(new UnfriendEvent(userId)); 

Ahora registra tu actividad en el bus de eventos y el evento se entregará a la actividad llamando al método onEvent:

 public void onEventMainThread(UnfriendEvent event) {...} 

De esta manera, desacoplar sus componentes lo que conduce a un diseño de software limpio y limpio, que es muy flexible a los cambios.

Puede usar un Cursor en su ListView para mostrar sus Datos. El servicio escribe / actualiza los datos en su ContentProvider. Al final de su transacción de base de datos de uso simple:

 getContext().getContentResolver().notifyChange(PROVIDER_URI,null); 

y su ListView se actualiza automáticamente.

En su lugar use

notifyDataSetChanged on onDestroy de servicio.

la vista de lista se actualizará

Puede utilizar este tutorial para la arquitectura adecuada de su código

desarrollar una aplicación con un servicio de fondo

Muestra cómo recibir notificaciones del servicio y actualizar la interfaz de usuario.

runOnUiThread se utiliza sobre todo antes de realizar llamadas AsyncTask. Creo que debería usar un controlador en su lugar (actualiza la interfaz de usuario y permite que se ejecute el subproceso). Trate de usar el controlador y vea lo que sucede

  • Android ListView onTouchEvent no siempre da ACTION_DOWN
  • ¿Por qué obtengo NullPointerException cuando uso setCurrentText o setText para TextSwitcher?
  • Establecer evento de clic de artículo en setOnItemClickListener de listview Android
  • Android: desplazamiento sin fin - ListView y Cursor
  • Establecer OnClick Listener en el botón dentro de la vista de lista en android
  • Adaptador de ListView personalizado lanza UnsupportedOperationException
  • El elemento se vuelve más grande al deslizar ListView
  • cuando listview desplazarse ese tiempo edittext establecer el valor predeterminado
  • ¿Cómo actualizar la vista de lista de Android?
  • Configuración del elemento ListView marcado desde Adapter
  • En Android, ¿cómo mostrar el diálogo de alerta con esquinas cuadradas como en Google Maps?
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.