10

我创建了一个服务,它在后台线程上同步来自网络的数据,并希望在服务完成时通知列表活动,以便它可以更新它的光标?最好的方法是什么?我正在考虑在服务完成后发送广播,但不确定这是否是最好的方法。服务完成后我需要重新查询光标,所以我不确定这是否适用于广播接收器?我有一段时间没有做很多android了,所以提前谢谢。

4

3 回答 3

16

当您连接到服务时,在您的服务中使用Handler注册客户端;ListActivity也就是说,在您的onServiceConnected方法中,向您的服务ListActivity发送一个Message,使您能够跟踪连接的客户端。然后,您可以简单地遍历您的这些客户端,并在您想要通知您的事情发生时Service向他们发送。有关更多信息,您可以查看我正在进行的项目中的代码: my和 my stubMessageServiceListActivityListActivityService

简而言之,在您的MainActivity, 启动并绑定到您的服务:

Intent i = new Intent(this, NetworkService.class);
startService(i);
bindService(i, networkServiceConnection, Context.BIND_AUTO_CREATE);

定义一个信使来响应来自服务的消息,例如:

Messenger messenger = new Messenger(new IncomingHandler());

class IncomingHandler extends Handler {
    @Override
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case NetworkService.MSG_SOMETHING:
                // do something here
                break;
            default:
                super.handleMessage(msg);
        }
    }
}

然后编写您的服务连接代码,例如:

private ServiceConnection networkServiceConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className, IBinder service) {
        networkService = new Messenger(service);
        try {
            Message msg = Message.obtain(null, NetworkService.MSG_REGISTER_CLIENT);
            msg.replyTo = messenger;
            networkService.send(msg);
            log.debug("Connected to service");

        } catch (RemoteException e) {
            // Here, the service has crashed even before we were able to connect
        }
    }

请注意,这replyTo是我们刚刚创建的信使。

在您的NetworkService中,通过以下方式跟踪连接的客户端:

ArrayList<Messenger> clients = new ArrayList<Messenger>();

并创建您的处理程序,例如:

class IncomingHandler extends Handler {
       @Override
       public void handleMessage(Message msg) {
           switch (msg.what) {
               case MSG_REGISTER_CLIENT:
                   log.debug("Adding client: " + msg.replyTo);
                   clients.add(msg.replyTo);
                   break;
               default:
                   super.handleMessage(msg);
                   break;
           }
       }
   }

然后,当您想将消息发送回您的MainActivity时,只需执行以下操作:

for (int i = 0; i < clients.size(); i++) {
    try {
        clients.get(i).send(Message.obtain(null, MSG_SOMETHING));
    } catch (RemoteException e) {
        // If we get here, the client is dead, and we should remove it from the list
        log.debug("Removing client: " + clients.get(i));
        clients.remove(i);
    }
}
于 2011-07-06T06:20:32.137 回答
6

如果您已经在使用支持库,则可以使用LocalBroadcastManager从服务中轻松触发广播,返回到您的活动,该活动将侦听正在发送的广播。

使用 LocalBroadcastManager 可确保只有您自己的应用程序才能接收广播,因此您不必担心泄露私人数据或打开潜在的安全漏洞。

另请参阅:如何使用 LocalBroadcastManager?

编辑(09/2014):

更好的方法是使用Otto(我最喜欢的)或GreenRobot/EventBus 之类的事件总线框架,以避免将组件耦合得太紧。

于 2012-08-09T11:25:02.753 回答
0

根据The Busy Coder's Guide to Advanced Android Development

事件总线是服务让应用程序的其他部分知道某些工作已完成的好方法。它提供了一个标准的通信通道(或“总线”),事件生产者和事件消费者可以连接到该通道。事件生产者只需要将事件交给总线;总线将处理将这些事件定向到相关消费者。这减少了生产者和消费者之间的耦合,有时甚至减少了获取和接收这些事件所需的代码量。

于 2018-02-12T05:37:38.670 回答