从广播接收器发送未绑定服务消息
我目前在我的android应用程序中有两项服务,为简单起见,我将拨打DataService
和CommunicationService
。 DataService
从内容提供者检索数据,然后将其序列化并传递到CommunicationService
。然后CommunicationService
将序列化的数据分成数据包,并一次发送给第三方设备一个数据包。 CommunicationService
知道发送下一个数据包的方式是通过BroadcastReceiver
。从广播接收器发送未绑定服务消息
CommunicationService
由DataService
开始,但是未结合的,并且具有比DataService
更长的寿命(其一旦其已经开始CommunicationService
结束时)。 BroadcastReceiver
调用CommunicationService
的方法让它知道现在是发送下一个数据包的时间的最佳方法是什么?我见过的两个想法是:
- 在BroadcastReceiver中绑定服务,调用方法并解除绑定。这似乎是最好的情况下非常糟糕的做法,最坏的情况是不可行的。
-
peekService
,尽管看起来这只适用于已经绑定了至少一次的服务,该服务将其排除。
我知道这个架构看起来有点混乱,但CommunicationService
的目标是能够在与第三方设备通信的多个应用中重复使用它;因此,它不能太紧密地绑定到特定的实现。
你BroadcastReceiver
可能会超时,所以不如把它叫IntentService
因为你的目标是让该服务为多个应用程序提供更新,每个应用程序应与服务(通知的潜力它注册更新),然后服务应该为每个注册的应用程序提供回调。
回调可以由CommunicationService
指定,并按照您似乎知道的跨进程通信的标准序列化限制执行您喜欢的任何功能。
所以基本的“流”会是这样的:
注册 - >有回调 BroadcastReceiver
回应 - >IntentService' -> execute callback ->
CommunicationService”
直接从BroadcastReceiver
调用什么主要的问题是,你的CommunicationService
可能已经死亡,可能导致暂停或NPE。通过回调,它可以检查服务是否存活,如果没有,则创建它。 IntentReceiver
应该是清醒的。并且提供回调对象允许您在多个同时调用和/或数据排队的情况下更好地控制线程安全代码。
只是为了确保我正确理解这一点: 'CommunicationService'应该扩展'IntentService'。它提供了回调的定义(通过接口或服务的客户端必须实现的内部类)。它提供了一种注册回调的机制(可能是一个静态公共函数,如果服务不存在就启动该服务)以及触发下一个数据包的机制(可能通过Intent?)。 (我在'IntentReceiver'上找不到任何暗示它已被弃用的帖子) – Aaron
是的 - 我的意思是'IntentService' - 我编辑了我的帖子,我犯了这个错误。您应该小心,通过接口定义回调,因为并非所有客户端都会正确实现序列化,这是必需的。但是,您可能能够定义灵活的回调对象API,这些API可以正确序列化,具体取决于您的使用情况。 – Jim
真棒,我认为那是有道理的!谢谢您的帮助。 – Aaron
你不能从'BroadcastReceiver'调用'context.bindService()'。你能解释一下为什么你不能只从接收器调用'startService()'?即使服务已经运行,它也会收到一个'onStartCommand()' – Karakuri
的调用。我的印象是,startService()会启动一个服务的新实例 - 没有意识到它只是表示现有的服务。这似乎是最简单的解决方案,所以我最终可能会用它!谢谢! – Aaron