Android广播接收器与服务[重复]

Posted

技术标签:

【中文标题】Android广播接收器与服务[重复]【英文标题】:Android Broadcast Receiver vs Service [duplicate] 【发布时间】:2013-01-11 00:25:36 【问题描述】:

我试图澄清android中广播接收器和服务之间的区别。

我了解活动可以通过调用startService 来启动服务。

广播接收器可以在代码或清单中注册,并且可以使用sendBroadcast 调用。

您什么时候会使用一个与另一个?

我知道多个广播接收器可以监听相同的意图,而服务不是这种情况。

【问题讨论】:

***.com/questions/3272763/… @CommonsWare - 如果您认为问题是“我应该将哪个应用程序组件用于非用户交互处理?”,它们是非常相关的。 @Chris - 服务本身不监听意图;您通常通过远程方法调用与它们进行交互。不过,服务可以以编程方式注册广播接收器以监视意图。 @Chris - wrt 接收者的数量,我想你可能正在考虑使用 startActivity (这只会导致一个活动接收意图)与 sendBroadcast (这将导致所有匹配的接收者都被发送意图) 重复,但是这个线程比主线程好。更多答案和有用的解决方案 【参考方案1】:

广播接收器

引用Dianne Hackborn on the Android Developers blog:

在处理广播时,应用程序有固定的时间(当前为 10 秒)来完成其工作。 如果在这段时间内没有完成,则认为应用程序行为不端,它的进程会立即进入后台状态,以便在需要时将其杀死以获取内存。

广播接收器受最大时间限制(通常为 10 秒),它们必须完成。

服务

如果您的操作需要更长的时间(连接到互联网可能需要一些时间)。最好在后台运行。为此,您绝对应该从接收器或 Activity 调用服务。他们最后被安卓操作系统杀死。

结论:

    一般来说,对您的应用程序很重要的所有工作(获取、解析、缓存、更新数据库)都应该移至Service,因为它们在 Android 上长期存在。正如您几乎认为所有的社交网站都有STICKY_SERVICES 那样做所有麻烦的工作。

    BroadcastReceiver主要用于启动服务。它通常取决于应用程序。大多数应用程序使用ConnectivityManager 来广播网络何时启动或关闭。在这些Service 的帮助下,由BroadcastReceiver 启动。

【讨论】:

+1 表示 10 秒 感谢您提及 10 秒。 这就是我要找的。谢谢:)【参考方案2】:

服务旨在在一段时间内在后台执行一项操作,无论用户在前台做什么(用户可能在活动之间切换)。一个很好的例子是音乐播放器服务 - 用户开始通过音乐播放器应用播放音乐,但当他们退出应用时,音乐继续播放。

服务对于跨多个应用程序提供/管理对资源的公共访问也很有用。这通常用于系统资源,例如传感器。

广播接收器旨在响应意图(通常是由服务或系统事件发送的意图),做某事并完成。此处的一个示例可能是用户将支持 NFC 的手机触摸标签,系统为其创建一个意图,然后注册的接收器处理它以更改某些设置(更改音量、打开蓝牙等)。

当通过 sendBroadcast 广播意图时,它将被发送到具有匹配意图过滤器的所有接收器。但是,需要注意的是,在 API26+ 中,清单中注册的大多数接收器在这种情况下不再被调用,请参阅the Google docs for more information。


示例 1:假设您想要公开一个函数(可从任何想要使用它的应用程序中获得),该函数要求网站计算与 Kevin Bacon 的分离度。

请注意,此示例是“做某事并返回”,而不是执行长时间运行的后台操作。

您可以通过多种方式实现这一点:

创建一个所有用户都编译到他们的应用程序中的库项目。

您的代码现在有多个副本,它们可能都是不同的版本。 您无法批处理或缓存请求,因为每个请求都是独立处理的。

创建一个广播接收器来处理每个请求。

您的应用程序注册一个广播接收器以接受询问培根问题的 Intent 每个应用程序都会发送一个 Intent 来提出问题。 广播接收器接受 Intent 并且 将请求传递给服务进行处理,该服务将 Intent 连同结果一起发送给请求者 向服务器发送请求,完成后将使用 Google Cloud Messaging 进行响应 因为所有请求都通过一个应用程序,您可以批量/缓存结果 这始终是异步的 API 是“意图” - 不是公开功能的最友好方式

创建一个服务来处理每个请求

您的应用程序创建一个服务来处理请求,并通过 Binder 或使用 AIDL 公开 API API 可以是同步的(直接调用并返回)或异步的(允许监听器注册并在结果就绪时调用监听器)。如果预计处理速度非常快,您应该只选择同步;服务器调用应该更频繁地异步处理 API 是“方法调用”——一种更友好的公开功能的方式

示例 2:您想要执行一些数据分析以找到数据中的一些模式

后台线程如果所有处理都发生在用户在同一个应用程序和同一个 Activity 中时,后台线程(或管理后台线程的 AsyncTask)将是一个好方法

服务 如果您希望允许用户在执行处理时退出应用程序(并在稍后通知他们结果),或者允许他们在同一个应用程序中进行多个活动在执行处理时,服务将是更好的方法

【讨论】:

不是“创建一个广播接收器来处理每个请求。”不稳定,因为您正在从可能被杀死的广播接收器发出异步请求? @pfrank - 良好的通话 - 接收者确实需要将其传递给服务,或者向服务器发送请求,该请求将在完成时通过 Google Cloud 消息传递进行通知。 (我已经用这个编辑了上面的内容) 这是我见过的最好的答案之一。谢谢 ~“跨多个应用程序对资源的共同访问”。但是可以导出 BroadcastReceiver,这将允许它从其应用程序之外的源接收消息 @pfrank 当不使用 API11 中引入的 'goAsync' 方法时这是真的,如果你需要在这个 API 之前支持,那么你需要创建一个服务,这样它就不会被杀死。【参考方案3】:

首先,阅读Broadcast Receiver 和Services 的文档。

您可以找到有用的教程here 和here。

最后,长话短说:

服务根据您的请求启动 (startService(intent))。 您可以将广播接收器视为意图侦听器。

【讨论】:

感谢您的链接。很好的帮助! ~"服务根据您的要求开始"。绑定服务并非如此,它们会自动启动。 例子很清楚~ 这里的“长话短说”结论对我的理解是不正确的,因为服务也可以纯粹从基于意图过滤器的意图开始。广播接收器是系统侦听器(来自操作系统的事件),或其他应用程序的侦听器。服务是您在应用程序内部使用的内容。

以上是关于Android广播接收器与服务[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Android 第六讲 广播接收器和服务

在android中卸载应用程序时调用广播接收器[重复]

android app中的服务为啥接收不到广播

[android] 代码注册广播接收者&利用广播调用服务的方法

Android入门:广播发送者与广播接收者

用于应用权限的 Android 广播接收器