2015-08-15 207 views
0

我目前在我的android应用程序中有两项服务,为简单起见,我将拨打DataServiceCommunicationServiceDataService从内容提供者检索数据,然后将其序列化并传递到CommunicationService。然后CommunicationService将序列化的数据分成数据包,并一次发送给第三方设备一个数据包。 CommunicationService知道发送下一个数据包的方式是通过BroadcastReceiver从广播接收器发送未绑定服务消息

CommunicationServiceDataService开始,但是未结合的,并且具有比DataService更长的寿命(其一旦其已经开始CommunicationService结束时)。 BroadcastReceiver调用CommunicationService的方法让它知道现在是发送下一个数据包的时间的最佳方法是什么?我见过的两个想法是:

  • 在BroadcastReceiver中绑定服务,调用方法并解除绑定。这似乎是最好的情况下非常糟糕的做法,最坏的情况是不可行的。
  • peekService,尽管看起来这只适用于已经绑定了至少一次的服务,该服务将其排除。

我知道这个架构看起来有点混乱,但CommunicationService的目标是能够在与第三方设备通信的多个应用中重复使用它;因此,它不能太紧密地绑定到特定的实现。

+0

你不能从'BroadcastReceiver'调用'context.bindService()'。你能解释一下为什么你不能只从接收器调用'startService()'?即使服务已经运行,它也会收到一个'onStartCommand()' – Karakuri

+0

的调用。我的印象是,startService()会启动一个服务的新实例 - 没有意识到它只是表示现有的服务。这似乎是最简单的解决方案,所以我最终可能会用它!谢谢! – Aaron

回答

1

BroadcastReceiver可能会超时,所以不如把它叫IntentService

因为你的目标是让该服务为多个应用程序提供更新,每个应用程序应与服务(通知的潜力它注册更新),然后服务应该为每个注册的应用程序提供回调。

回调可以由CommunicationService指定,并按照您似乎知道的跨进程通信的标准序列化限制执行您喜欢的任何功能。

所以基本的“流”会是这样的:

注册 - >有回调 BroadcastReceiver回应 - >IntentService' -> execute callback -> CommunicationService”

直接从BroadcastReceiver调用什么主要的问题是,你的CommunicationService可能已经死亡,可能导致暂停或NPE。通过回调,它可以检查服务是否存活,如果没有,则创建它。 IntentReceiver应该是清醒的。并且提供回调对象允许您在多个同时调用和/或数据排队的情况下更好地控制线程安全代码。

+0

只是为了确保我正确理解这一点: 'CommunicationService'应该扩展'IntentService'。它提供了回调的定义(通过接口或服务的客户端必须实现的内部类)。它提供了一种注册回调的机制(可能是一个静态公共函数,如果服务不存在就启动该服务)以及触发下一个数据包的机制(可能通过Intent?)。 (我在'IntentReceiver'上找不到任何暗示它已被弃用的帖子) – Aaron

+0

是的 - 我的意思是'IntentService' - 我编辑了我的帖子,我犯了这个错误。您应该小心,通过接口定义回调,因为并非所有客户端都会正确实现序列化,这是必需的。但是,您可能能够定义灵活的回调对象API,这些API可以正确序列化,具体取决于您的使用情况。 – Jim

+0

真棒,我认为那是有道理的!谢谢您的帮助。 – Aaron