3

我有一个后台服务,它从服务器接收消息,并通过这些消息更新显示在 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 对象属性的更改。

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

5 回答 5

9

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

  1. 在您的服务中,广播一个带有更新信息的意图。
  2. Activitywhere is ,为您的更新事件ListView创建并注册。BroadcastReceiverIntentFilter
  3. onReceiveBroadcastReceiver处理更新事件的方法中,例如更新列表。
于 2012-11-04T10:49:18.663 回答
1

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

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

并且您的 ListView 会自动更新。

于 2012-11-07T11:52:18.990 回答
1

而是使用

notifyDataSetChanged onDestroy 服务。

列表视图将被刷新

于 2013-06-21T12:46:31.080 回答
1

服务通常应该独立于 UI 问题。将服务和 UI 相关的东西解耦的一个好方法是事件总线模式。对于 Android,请查看https://github.com/greenrobot/EventBus

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

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

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

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

像这样,您将组件解耦,从而产生整洁干净的软件设计,这对更改非常灵活。

于 2012-11-10T12:31:17.953 回答
0

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

开发具有后台服务的应用程序

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

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

于 2012-11-07T10:50:52.597 回答