2012-11-04 129 views
0

我在写一个运行后台服务的应用程序,它与远程服务器进行通信。 当服务器向我发送一条新消息时,我需要更新UI中表示的对象,然后更新UI视图以表示对象的新状态(例如,如果对象的背景属性为真 - 设置视图的背景为绿色,如果为假,则将视图的背景设置为红色)。Android服务通信

我正在使用列表视图来显示所有这些对象的ArrayList抛出一个ArrayAdapter。

我有一个应用程序对象(名为应用程序)的静态引用,我有一个CurrentActivity属性存储当前活动正在运行(或null,如果用户界面已关闭)。

我正在使用此代码更新UI:

在我的服务

onNewMessage(boolean backgruond) 
{ 
    if (app.getCurrentActivity != null) 
    app.getCurrentActivity.onNewMessage(background); 
} 
在我的活动

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

,虽然日志返回正确的背景状态,该视图不会使用notifyDataSetChanged()刷新;

我试图发送消息给Activity抛出BroadcastRecevier,但它更复杂,因为我有很多来自服务器的消息,我将不得不注册很多接收者。 再说 - 我不明白为什么会recevier工作,而这个机制不会..工作方法的

例子更新的ListView:

ListViewActivity - 继承自BaseActivity:

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

BaseActivity(超类延伸活动):

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); 
} 

这一项工作,它改变背景ListView中的颜色。

不灵例如 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); 
} 

不进行更新......我真的不能明白为什么..

回答

0

我有有一个CurrentActivity属性存储当前正在运行的活动(如果UI已关闭,则为null)

我不推荐这种做法。它依赖于您始终如一地更新Application数据成员,并且它增加了您的服务与您的用户界面之间的耦合。

尽管Log返回正确的背景状态,但视图不会使用notifyDataSetChanged()刷新;

这看起来似乎没有更改适配器中的数据。当然,代码中没有证据表明您在此处更新了适配器中的数据。

顺便说一句,你在这里显示的代码片段都不可能编译(首先不是有效的Java,第二个有错字)。

我有很多来自服务器的消息,我将必须注册多个接收者

不,你必须注册一个接收器,并在onReceive(),使用if声明(或可能一个switch,如果你愿意)区分一个消息。

+0

我已经显示的代码片段仅仅是我为这个问题写的一个例子..我确实改变了适配器中的数据 - 我已经改变了属性indside我的对象 - 这个对象是在里面的arraylist这个adpter –

+0

我不是说他们是无用的 - 他们应该证明我的问题... –

+0

但是 - 不notifyOnDataSetChanged应该更新视图,如果对象属性已更改? –

0

除了CommonsWare所说的,我认为objectonNewMessage的第一行是视图。 setBackround接受int参数,而不是boolean

使用0xFF00FF00代表绿色,0xFFFF0000代表红色。

顺便说一句,这是一个非常不好的做法,以保持Context对象的静态引用和它的派生类(ApplicationActivityContext两个派生,并保持它们的静态引用可能会导致严重的内存泄露。更多here

改为使用BroadcastReceiver。与你描述他们相比,他们更简单 - 你只需要一个。

+0

它不是一个视图 - 它只是一个对象的例子,我在我的问题中描述了ListView应该如何处理该属性 –

+0

Like CommonsWare猜测,notifyDataSetChanged没有执行任何操作,因为您没有更改对象列表(更改列表中的单个对象不会计数,仅更改列表本身)。在这里阅读:http://stackoverflow.com/questions/3669325/notifydatasetchanged-example/5092426#5092426 – Jong

+0

所以如何来一些功能的财产的变化工作,有些不是? –