Android ListView notifyDataSetChanged() from Service
android, android-arrayadapter, listview
Solution
Don't mix business logic. It looks so complicated that is hard to read.
- In your service, broadcast an intent with information about update.
- In `Activity` where `ListView` is, create and register `BroadcastReceiver` with `IntentFilter` for your update events.
- In `onReceive` method of your `BroadcastReceiver` handle update events, for example update list.
Problem
I have a background service which receive messages from a server and with those message it updates inner properties of objects which are shown in a ListView. I always uses the runOnUiThread method to run the listArrayAdapter.notifyOnDataSetChanged() command. From some reason sometimes the ListView is refreshed and it does show me the property update and sometimes it doesn't.. For testing i've added a "refresh" Button to my ListView and when it pressed the listArrayAdapter.notifyOnDataSetChanged() is executed. Every click on the button the view is refreshed perfectly.. I can't really understand why when trying to refresh from the service it doesn't always work but i think i maybe not always runs on the UIThread... I'm really hopeless and will glad to get help.. My Code ServerConnectionManager.java - extends Service ``` //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 - a class that handle all application responses to server messages: ``` 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 - an Activity which set all default configuration for all Activities which extends it ``` //in this exemple the BaseActivity method does nothing but the ListViewActivity.java method override it public void onUnFriend(FacebookUser facebookUser) { } ``` ListViewActivity.java - extends BaseActivity and have a ListView in it which should reflect the change in the FacebookUser object property which being made in public void onUnFriend(FacebookUser facebookUser, boolean isYouRemovedClient) in 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; } ```