IntentService 作为 Service 的子类,它能够将我们需要的操作放到 工作线程 进行处理。通过重写
onHandleIntent()方法,此方法会自动处理我们发出的每一个 Intent,在工作线程中执行任务。
前言
众所周知,但我们想要启动一个 Service,需要在另一个组件中调用 startService(),从而调用 Service 中的 onStartCommand() 方法.
Service 拥有自己的生命周期,并可以在后台无限期的运行(和 Windows 中的 Service 很像)。
注意1:即使是调用者(启动服务的组件)被销毁,都不能影响 Service 的运行。我们需要在另一个组件中调用 stopService() 或者在服务中调用 stopSelf() 来停止服务。
注意2:我见到到一些 Android 开发人员,因为对 Service 不熟悉,想当然的认为每当我们启动了一个 Service,也就意味了开了一个子线程,这种想法是错误的。
实际情况是:默认情况下,服务和服务声明的应用运行在同一个进程中,而且运行在主线程中。所以说,如果 Service 需要处理一些耗时操作,我们需要在 Service 中开启一个工作线程来处理这些任务。
- Service : 这是服务的基类。默认情况下运行于主线程中。
- IntentService : Service 的子类,能够将我们的请求在工作线程中逐一处理。如果你的业务需求是不需要同时处理多个请求,那么 IntentService 将会是你最好的选择。我们只需实现
onHandleIntent()方法即可,该方法会处理每个请求,并在后台执行。
IntentService
我们来详细说一说 IntentService 的功能:
- 创建默认的 工作线程,来处理在
onStartCommand()中接受到的所有 Intent; - 创建 工作队列,用于将 Intent 逐一传递给
onHandleIntent()实现,这种机制,让我们告别多线程的苦恼; - 在处理完工作队列中的所有 Intent 后,会自动停止服务,也就是说,你永远不必调用停止 Service 的方法;
- 提供 onBind() 的默认实现(返回
null); - 提供 onStartCommand() 的默认实现,可将 Intent 依次发到 工作队列 中和 onHandleIntent() 实现;
也就是说,我们只需提供 IntentService 的构造函数,以及在 onHandleIntent() 来处理相应逻辑即可。
1 | public class TestIntentService extends IntentService { |
注意:通常情况下,我们只需实现一个构造器和 onHandleIntent() 方法即可,如果你还想重写其他回调方法(如:onCreate(), onStartCommand() etc.),你需要确保你调用了父类的实现,以便 IntentService 能够正确的处理工作线程的生命周期。
如下所示:
1 |
|
除了 onHandleIntent() 方法外,我们还有一个无需调用父类实现的方法是 onBind()(仅当绑定服务时,才需要实现).
Service 拓展
通过上面一节的介绍,我们可以知道利用 IntentService 可以非常方便的同步处理一些 Intent,但是当业务场景转换到需要同时执行多个 Intent 时,IntentService 就不能够满足我们的需求了,这时,我们需要扩展 Service 类。
下面的示例代码中,我们对每一个请求,都放在工作线程中执行,且每次只处理一个请求。
1 | public class TestService extends Service { |
这个示例并不是同时处理多个 Intent,因为不太建议这么做,如果实在需要,我们可以在 onStartCommand() 方法中对每个 Intent 单独创建一个子线程,然后立即运行这些线程。
注意:onStartCommand() 方法必须返回一个整数类型。用于描述系统应该如何处理如果服务被终止了的情况。我们返回的整数类型必须是下面三种值其一:
如果系统在 onStartCommand() 返回后终止服务,则除非有挂起 Intent 要传递,否则系统不会重建服务。这是最安全的选项,可以避免在不必要时以及应用能够轻松重启所有未完成的作业时运行服务。
如果系统在 onStartCommand() 返回后终止服务,则会重建服务并调用 onStartCommand(),但绝对不会重新传递最后一个 Intent。相反,除非有挂起 Intent 要启动服务(在这种情况下,将传递这些 Intent ),否则系统会通过空 Intent 调用 onStartCommand()。这适用于不执行命令、但无限期运行并等待作业的媒体播放器(或类似服务)。
如果系统在 onStartCommand() 返回后终止服务,则会重建服务,并通过传递给服务的最后一个 Intent 调用 onStartCommand()。任何挂起 Intent 均依次传递。这适用于主动执行应该立即恢复的作业(例如下载文件)的服务。
本文参考: