从服务(LocalService)与活动(Activity)进行通信 - Android 最佳实践

20

常见场景-使用后台服务轮询服务器的活动。

该服务通过AlarmManager定期运行,并为活动执行任务(用户按下按钮,从服务器获取某些内容)。

我想知道这里的最佳实践。我认为最好的设计是Android LocalService示例:http://developer.android.com/reference/android/app/Service.html#LocalServiceSample

然而,在该示例中,活动有一个对该活动mBoundService的引用,但没有反向连接(服务没有办法调用活动)。

服务如何调用活动是最佳方式?

我应该使用意图、广播接收器、消息?怎么用?

3个回答

9
我认为最好的设计是 Android LocalService 示例: http://developer.android.com/reference/android/app/Service.html#LocalServiceSample 我不这样做。使用尽可能松散的耦合。因此,平均而言,应该使用命令模式和startService()而不是绑定模式和bindService()。值得注意的是,在处理配置更改(例如屏幕旋转)时,绑定会有些麻烦。
服务调用活动的最佳方法是什么?我使用意图、广播接收器、消息吗?怎么用?
请参见Notify activity from service

嗯,实际上我是根据你的教程进行的:https://github.com/commonsguy/cw-andtutorials/tree/master/18-LocalService/Patchy/src/apt/tutorial 这种方法有什么不好的地方吗? - paulpooch
1
@paulpooch:嗯,让我们说我会在接下来的几个月里重新编写所有Patchy教程。 - CommonsWare
1
我觉得我需要在这里提供一个链接,指向@CommonsWare的另一篇文章,在那里他说当绑定到一个Application对象而不是Activity时,Service绑定可以减少痛苦。https://dev59.com/PWUp5IYBdhLWcg3wf3us#15235902 - Mixaz

1

如果您需要使用bindService()实现紧密耦合的活动,通信方式取决于谁发起通信。

如果服务是发起方(例如由于闹钟有一些新信息要共享),它通常会发送广播。

如果活动是发起方(例如您的示例“从服务器获取某些内容”),则可以使用AsyncTask或类似方法异步处理。也就是说,您可以在AsyncTask.doInBackground()中从服务器获取数据,并在AsyncTask.onPostExecute中将结果返回给活动。如果请求的操作预计需要很长时间,则此场景可能会更加复杂 - 在这种情况下,我会将其解耦,并从服务中发送广播回来。


0

如下所述 这里

当您想要从服务通信到未启动服务的Activity或Fragment,或者想要从服务通信到多个Activity/Fragment时,可以使用Event Bus或Broadcast Intents,因为它们可以在任何实现它们的Activity或Fragment中接收事件的回调。如果您想要从服务通信到启动服务的Activity/Fragment,则可以使用Pending Intent或Messenger,因为它们可以被放入Intent extra并传递给Service。
Pending Intent
我们可以使用createPendingResult()创建一个新的PendingIntent对象,您可以将其交给Service使用,并在onActivityResult(int, int, Intent)回调中向您的Activity发送结果数据。
Event Bus
您可以让服务引发事件,以便Activity或Fragment可以使用Event Bus监听并响应。
Messenger Messenger是可包裹的,因此可以将其放入Intent extra中,因此您的Activity可以将此Messenger传递给Service。Service将使用任何需要发送的数据填充Message对象。
Broadcast Intents
Service可以发送广播,Activity可以对其进行响应。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接