0

I'm writing an application which run a background Service which communicate with a remote server. when the server sends me a new message, i need to update an object which is represent in the UI and then to update the UI View to represent the new state of the object (for example if the object's background propery is true - set the background of the View to green and if false set the background of the view to red).

I'm using a list view to show all an ArrayList of all those objects throw an ArrayAdapter.

I have an Application object (named app) for static reference and i have there a CurrentActivity property which store the current activity running (or null if the UI is closed).

i'm using this code to update the UI:

in my Service:

onNewMessage(boolean backgruond)
{
  if (app.getCurrentActivity != null)
     app.getCurrentActivity.onNewMessage(background);
}

in my Activity:

onNewMessage(boolean background)
{
  object.setBackground(bacground);
  Log.d("Background", String.valueof(background));
  runOnUiThread(new Runnable() {
      @Override
      public void run()
      {
        arrayAdapter.notifyDataSetChanged();
      }
  });
}

and although the Log returns the right background state, the view isn't refreshing with the notifyDataSetChanged();

i've tried to send message to Activity throw BroadcastRecevier but it much more complicated because i have lots of messages coming from the server and i will have to register many receivers. And besides - i don't understand why would the recevier work and this mechanism wont..

example of working method which updates the ListView:

ListViewActivity - inheritance from BaseActivity:

@Override
public void onUnFriend(FacebookUser facebookUser, boolean isYouRemovedClient) 
{               
    super.onUnFriend(facebookUser, isYouRemovedClient);
    updateView();
}

BaseActivity (the super class which extends Activity):

public void onUnFriend(FacebookUser facebookUser, boolean isYouRemovedClient)
{                           
    facebookUser.setApplicationFriend(false);
    app.getApplicationFriends().remove(facebookUser);
    app.getDatabaseManager().deleteApplicationFriend(facebookUser.getId());     
    if (isYouRemovedClient)
        app.showToast(facebookUser.getName() + " has removed from your friends", true);
    else
        app.showToast(facebookUser.getName() + " has removed you from friends", true);
}   

this one works and does change the background color in the ListView.

not working example ListViewActivity:

@Override
public void onFriendRequestAccepted(FacebookUser facebookUser, boolean showDialog) {
    super.onFriendRequestAccepted(facebookUser, showDialog);
    updateView();
}

BaseActivity:

public void onFriendRequestAccepted(FacebookUser facebookUser, boolean showDialog) 
{   
    facebookUser.setApplicationFriend(true);
    app.getApplicationFriends().add(facebookUser);
    app.getDatabaseManager().addApplicationFriend(facebookUser);
    if (showDialog)
        app.showNewEventActivity(facebookUser, EventDialogManager.EVENT_FRIEND_ACCEPTED);
}

no update is made... i can't really understand why..

Asaf Nevo
  • 11,338
  • 23
  • 79
  • 154

2 Answers2

0

i have there a CurrentActivity property which store the current activity running (or null if the UI is closed)

I do not recommend this practice. It relies upon you consistently and reliably updating that Application data member, and it increases the coupling between your service and your UI.

and although the Log returns the right background state, the view isn't refreshing with the notifyDataSetChanged();

It would appear that you did not change the data in the adapter. Certainly, there is no evidence in the code that you have here that you updated the data in the adapter.

BTW, neither of the code snippets you have shown here are likely to compile (first is not valid Java, second has a typo).

i have lots of messages coming from the server and i will have to register many receivers

No, you will have to register one receiver, and in onReceive(), use an if statement (or perhaps a switch, if you prefer) to distinguish one message from another.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • the code snippets i have shown is just an example i've written for the question.. and i did change the data in the adapter - i've changed the property indside my object - and this object is inside the arraylist of the adpater – Asaf Nevo Nov 04 '12 at 16:02
  • but again - isn't notifyOnDataSetChanged should update the view if an object property has changed ? – Asaf Nevo Nov 04 '12 at 16:15
0

In addition to what CommonsWare said, I assume that object in the first line of your onNewMessage is the view. setBackround accepts an int parameter, not a boolean.

Use 0xFF00FF00 for green and 0xFFFF0000 for red.

By the way, it's a very bad practice to keep static references of Context objects and it's derived classes (Application and Activity both derive from Context, and keeping a static reference of them may lead to serious memory leaks. Read more here.)

Use a BroadcastReceiver instead. They are much more simple comparing to how you described them - you only need one.

Jong
  • 9,045
  • 3
  • 34
  • 66
  • it's not a view - it just an example of an object and I've describe in my question how does the ListView should work with that property – Asaf Nevo Nov 04 '12 at 16:04
  • Like CommonsWare guessed, `notifyDataSetChanged` does nothing because you didn't change your objects list (Changing a single object of the list doesn't count. Only changing the list itself). Read here: http://stackoverflow.com/questions/3669325/notifydatasetchanged-example/5092426#5092426 – Jong Nov 04 '12 at 16:15
  • so how come for some functions the change of a property works and for some doesn't ? – Asaf Nevo Nov 04 '12 at 16:19
  • i'm updating my question with 2 examples: one updating the listView and the other doesn't... i will be thanks full if you could have a look – Asaf Nevo Nov 04 '12 at 16:21
  • `notifyDataSetChanged` will do something only if the **list** itself is updated - for example, calling `insert`, `remove`, `clear`. You don't call any of these methods. – Jong Nov 04 '12 at 16:23