来自Service的Android ListView notifyDataSetChanged()

时间:2012-10-30 18:07:43

标签: android listview android-arrayadapter

我有一个后台服务,它接收来自服务器的消息,并使用这些消息更新ListView中显示的对象的内部属性。

我总是使用runOnUiThread方法来运行listArrayAdapter.notifyOnDataSetChanged()命令。

出于某种原因,有时会刷新ListView并且它确实向我显示属性更新,有时它不会...

为了测试我已经为我的ListView添加了一个“刷新”按钮,当它按下时,执行listArrayAdapter.notifyOnDataSetChanged()。

按钮上的每次点击都会完美刷新视图..

我无法理解为什么当尝试从服务中刷新它并不总是有效但我想我可能并不总是在UIThread上运行......

我真的很无望,很乐意得到帮助..

我的代码

ServerConnectionManager.java - 扩展服务

//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 - 一个处理服务器消息的所有应用程序响应的类:

    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 - 一个为所有扩展它的活动设置所有默认配置的活动

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

}

ListViewActivity.java - 扩展BaseActivity并在其中包含一个ListView,它应该反映在ServerResponseManager中的public void onUnFriend(FacebookUser facebookUser,boolean isYouRemovedClient)中生成的FacebookUser对象属性的变化。 / p>

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

5 个答案:

答案 0 :(得分:9)

不要混淆业务逻辑。它看起来很复杂,难以阅读。

  1. 在您的服务中,使用有关更新的信息广播意图。
  2. Activity所在的ListView中,为BroadcastReceiver创建并注册IntentFilter以获取更新事件。
  3. onReceive句柄更新事件的BroadcastReceiver方法中,例如更新列表。

答案 1 :(得分:1)

您可以在ListView中使用Cursor来显示您的数据。 服务在ContentProvider中写入/更新数据。在数据库事务结束时,您可以使用:

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

并自动更新ListView。

答案 2 :(得分:1)

服务通常应独立于UI关注点。事件总线模式是分离服务和UI相关内容的好方法。对于Android,请查看https://github.com/greenrobot/EventBus

在ServerConnectionManager中,您可以发布一个事件:

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

现在将您的活动注册到事件总线,并通过调用onEvent方法将事件传递给活动:

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

像这样,您可以将组件分离,从而实现整洁干净的软件设计,这对于更改非常灵活。

答案 3 :(得分:1)

改为使用

onDestroy of service上的notifyDataSetChanged。

列表视图将刷新

答案 4 :(得分:0)

您可以使用本教程来正确构建代码

developing an app with a background service

它显示了如何从服务接收通知并更新UI。

runOnUiThread主要在进行AsyncTask调用之前使用。我认为你应该使用一个处理程序(它更新UI并允许线程运行)。尝试使用处理程序,看看会发生什么