Android服务通知活动完成的最佳方式?

发布于 2024-11-18 19:05:19 字数 166 浏览 3 评论 0 原文

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

I created a service which syncs data from the web on a background thread and want to notify a list activity when the service has completed so it can update it's cursor? What would be the best way to do this? I'm thinking of sending a broadcast when the service is done but not sure if that's the best way to do it. I need to requery the cursor when the service has finished so I'm not sure if that will work well with broadcast receivers? I haven't done alot of android in awhile so thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

世界和平 2024-11-25 19:05:19

在您的服务中使用 Handler,当您的 ListActivity 连接到服务时注册客户端;也就是说,在 ListActivityonServiceConnected 方法中,向您的服务发送一条 Message,以便您能够跟踪连接的客户端。然后,您可以简单地在 Service 中循环访问这些客户端,并在您想要通知您的 Service 中发生某些情况时向它们发送 Message。关于ListActivity。有关更多信息,您可以查看我正在进行的项目中的代码:我的 ListActivity 和我的 Service 存根

简而言之,在您的 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);
    }
}

Use a Handler in your service that registers a client when your ListActivity connects to the service; that is, in your onServiceConnected method in your ListActivity, send a Message to your service that enables you to keep track of connected clients. Then you can simply loop through these clients in your Service and send them a Message when something takes place in your Service that you want to notify your ListActivity about. For more information you can look at code in an on-going project of mine: my ListActivity and my Service stub.

In short, in your MainActivity, start and bind to your service with:

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

Define a messenger to respond to messages from the service like:

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

And then write your service connection code like:

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

Note that the replyTo is the messenger we just created.

In your NetworkService, keep track of connected clients with:

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

and create your handler like:

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

Then, when you want to send a message back to your MainActivity, just do something like the following:

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);
    }
}
滥情空心 2024-11-25 19:05:19

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

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

另请参阅:如何使用 LocalBroadcastManager?

编辑(09/2014):

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

If you're already using the support library, you could just as easily fire a broadcast from the service using the LocalBroadcastManager back to your activity that would listen for the broadcast being sent.

Using LocalBroadcastManager ensures only your own application would ever receive the broadcast so you don't have to worry about leaking private data or opening up potential security holes.

Also see: how to use LocalBroadcastManager?

EDIT (09/2014):

A better way to do this would be to use an event bus framework like Otto (my favourite) or GreenRobot/EventBus to avoid coupling your components too tightly.

素手挽清风 2024-11-25 19:05:19

根据忙碌的程序员高级 Android 开发指南

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

As per The Busy Coder's Guide to Advanced Android Development

An Event Bus is a great way for the service to let other pieces
of the app know that certain work was done. It provides a standard
communications channel (or “bus”) that event producers and event
consumers can hook into. Event producers merely need to hand the event
to the bus; the bus will handle directing those events to relevant
consumers. This reduces the coupling between the producers and
consumers, sometimes even reducing the amount of code needed to source
and sink these events.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文