Android平台中的Service vs IntentService


774

我正在寻找的东西,可以用做一个例子IntentService,不能用一个来完成Service(反之亦然)?

我也相信IntentServicea在不同的线程中运行,而a Service没有。因此,据我所知,在自己的线程中启动服务就像启动IntentService。那是对的吗?


45
IntentService is used for short tasks (etc) and a service is for long ones你在哪里读的?
njzk2

9
另外,我建议您阅读IntentService的源代码。它很清楚它是什么,它做什么。
njzk2

1
看到您发表评论后,我编辑了问题。
roiberg 2013年


2
以前的评论中的链接(作者greg7gkb)是一本好书。
DSlomer64 '16

Answers:


1348

Tejas Lagvankar 就此主题写了一篇不错的文章。以下是Service和IntentService之间的一些主要区别。

什么时候使用?

  • Service可以用于没有UI的任务中,但不应太长。如果需要执行长任务,则必须使用Service中的线程。

  • IntentService可以在较长的任务中使用通常与主线程没有沟通。如果需要通信,则可以使用主线程处理程序或广播意图。另一个使用情况是需要回调(意图触发的任务)时。

如何触发?

  • 服务是通过调用方法所触发startService()

  • IntentService使用触发的意图,它产生一个新的工作线程和方法onHandleIntent()调用这个线程。

触发自

  • 服务IntentService可以从任何线程,活性或其它应用程序组件触发。

运行

  • 服务在后台运行,但在应用程序的主线程上运行。

  • IntentService运行在一个单独的工作线程。

局限性/缺点

  • 服务可能会阻止该应用程序的主线程。

  • IntentService不能并行运行的任务。因此,所有连续的意图都将进入工作线程的消息队列,并将按顺序执行。

什么时候停止?

  • 如果您实施服务,则您有责任在服务完成时通过调用stopSelf()或停止服务stopService()。(如果只想提供绑定,则不需要实现此方法)。

  • 在处理所有启动请求之后,IntentService将停止服务,因此您无需调用stopSelf()


11
简短而有趣,但是如果您通过CommonsWare编辑您的答案(包括分数),则效果会更好,因为很多人只会阅读已接受或最受支持的答案
Shirish Herwade 2014年

12
@Darpan服务是一个应用程序组件,可以在后台执行长时间运行的操作,并且不提供用户界面。服务在其托管过程的主线程中运行。该服务不会创建自己的线程,也不会在单独的进程中运行(除非另行指定)。这意味着,如果您的服务要执行任何CPU密集型工作或阻止操作(例如MP3播放或联网),则应在服务中创建一个新线程来执行该工作。
何塞·胡安·桑切斯

8
“必须从主线程触发IntentService。” 你确定吗?在我的MainActivity onCreate()内部,当我从新线程(下面的代码)调用IntentService时,它仍然对我有用。new Thread(new Runnable(){@Override public void run(){Intent intent = new Intent(context,HelloIntentService.class); startService(intent);}))。start();
Ashok Bijoy Debnath,2014年

9
@AshokBijoyDebnath你是对的!该服务IntentServices可以从任何线程,活动或其他应用程序组件启动。我刚刚编辑了答案的文本以解决此问题。感谢您的编辑建议!:)
何塞·胡安·桑切斯

2
没问题,去吧!
何塞·胡安·桑切斯

165

如果有人可以向我展示一个示例,该示例可以用IntentService和而不可以用Service和来完成。

根据定义,这是不可能的。IntentServiceServiceJava编写的的子类。因此,通过包含所使用的相关代码位IntentService,a Service可以做什么都可以做IntentService

用自己的线程启动服务就像启动IntentService。不是吗

an的三个主要特征IntentService是:

  • 后台线程

  • Intent传递给的s 的自动排队onStartCommand(),因此,如果Intent正在onHandleIntent()后台线程上处理,则其他命令排队等候

  • 队列为空后IntentService,通过调用来自动关闭stopSelf()

可以通过a来实现所有这些,Service而无需扩展IntentService


6
有点晚了,但是我发现Servicewith startService只能在运行ANR之前运行大约10秒钟- IntentService从广播意图开始似乎没有这个限制
edthe第三版,2013年

16
@edthethird:那是因为您正在捆绑主应用程序线程。在主应用程序线程上调用所有组件上的所有生命周期方法,包括onStartCommand()Service。您不能在不冻结UI的情况下将线程占用超过几毫秒的时间,并且如果花费很多时间,您将获得相当于ANR的服务。
CommonsWare

3
是的,我评论得太早了。我在做的工作onStartCommand,而不是onHandleIntent-看起来就像onStartCommand是在UI线程上运行,但一个单独的线程中催生的onHandleIntent执行。
edthethird

3
@IgorGanapolsky:如果没有更多工作要做,则IntentServiceonHandleIntent()返回后自行调用。
CommonsWare,2015年

1
问题不是英语,而是编程。例如,“我已关闭应用程序”没有精确的定义,因此我无法告诉您发生这种情况时会发生什么。我也不知道“我已关闭该应用程序”与“将在1小时后下载”有何关系。您可以考虑问一个单独的堆栈溢出问题,在这里可以提供“ 1小时后将下载” 的最小可复制示例。在这里,您可以详细说明“我已经关闭了该应用程序”的意思(例如,用户具体关闭了该应用程序是什么?)。
CommonsWare

39

服务

  • 调用者 startService()
  • 从任何触发 Thread
  • 继续 Main Thread
  • 可能会阻塞主(UI)线程。始终在服务中使用线程来完成长任务
  • 任务完成后,我们有责任通过致电stopSelf()stopService()

意图服务

  • 它执行长时间的任务,如果需要通信,通常不与主线程通信,然后由HandlerBroadcastReceiver
  • 通过调用 Intent
  • 触发于 Main Thread
  • 在单独的线程上运行
  • 无法并行运行任务,并且多个意图在同一工作线程上排队。

19

不要重新发明轮子

IntentService扩展了Service类,这显然意味着它IntentService是出于相同目的而有意制造的。

那么目的是什么?

`IntentService的目的是使我们的工作更轻松地运行后台任务,而无需担心

  • 创建工作线程

  • 队列由一个处理多个请求一个(Threading

  • 摧毁 Service

所以NOService能做到其中的任何任务IntentService会做。如果您的要求符合上述条件,则不必在Service类中编写这些逻辑。所以不要重新发明轮子,因为IntentService它是发明的轮子。

“主要”区别

服务在UI线程上运行,而IntentService在单独的线程上运行

您何时使用IntentService?

当您要一个活动执行一个范围之外的多个后台任务时,这IntentService是完美的选择。

怎么IntentService制成的Service

普通服务在UI线程上运行(默认情况下Activity,任何Android组件类型在UI线程上运行BroadcastReceiver,,ContentProviderService)。如果您需要做一些工作可能需要一段时间才能完成,那么您必须创建一个线程。如果有多个请求,则必须处理synchronizationIntentService提供了一些默认实现,可以为您完成这些任务。
根据开发者页面

  1. IntentService 创建一个工作线程

  2. IntentService创建一个工作队列,将请求onHandleIntent()一一发送给方法

  3. 没有工作时再IntentService调用stopSelf()方法
  4. 提供onBind()null的方法的默认实现
  5. onStartCommand()Intent请求发送到WorkQueue并最终发送到的默认实现onHandleIntent()

15

在接受的答案中加分:

查看Android API中IntentService的用法。例如:

public class SimpleWakefulService extends IntentService {
    public SimpleWakefulService() {
        super("SimpleWakefulService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {  ...}

要为您的应用创建IntentService组件,请定义一个扩展IntentService的类,并在其中定义一个覆盖onHandleIntent()的方法。

另外,请参阅IntentService的源代码,它是构造函数和生命周期方法,例如onStartCommand ...

  @Override
    public int More ...onStartCommand(Intent intent, int flags, int startId) {
       onStart(intent, startId);
        return mRedelivery ? START_REDELIVER_INTENT : START_NOT_STICKY;
    }

将AsyncTask一起提供服务是有效负载不大的许多用例的最佳方法之一。或者只是创建一个扩展IntentSerivce的类。从Android 4.0版开始,所有网络操作都应处于后台进程,否则应用程序编译/构建将失败。与用户界面分开的线程。AsyncTask类提供了从UI线程触发新任务的最简单方法之一。有关此主题的更多讨论,请参阅博客文章。

来自Android开发人员指南

IntentService是Services的基类,可根据需要处理异步请求(表示为Intent)。客户端通过startService(Intent)调用发送请求;服务会根据需要启动,依次使用工作线程处理每个Intent,并在工作用尽时自行停止。

IntentService中使用的设计模式

:此“工作队列处理器”模式通常用于从应用程序的主线程卸载任务。存在IntentService类是为了简化此模式并注意机制。要使用它,请扩展IntentService并实现onHandleIntent(Intent)。IntentService将接收Intent,启动工作线程,并在适当时停止服务。

所有请求都在单个工作线程上处理-它们可能会花费必要的时间(并且不会阻塞应用程序的主循环),但是一次只会处理一个请求。

IntentService类提供了用于在单个后台线程上运行操作的简单结构。这使其可以处理长时间运行的操作,而不会影响用户界面的响应能力。另外,IntentService不受大多数​​用户界面生命周期事件的影响,因此它会在可能会关闭AsyncTask的情况下继续运行。

IntentService有一些限制:

它不能直接与您的用户界面进行交互。要将其结果放入用户界面,您必须将其发送到活动。工作请求按顺序运行。如果某个操作正在IntentService中运行,并且您向它发送了另一个请求,则该请求将等待直到第一个操作完成。在IntentService上运行的操作不能被中断。但是,在大多数情况下

IntentService是进行简单后台操作的首选方式

**

凌空图书馆

有一个名为volley-library的库,用于开发android网络应用程序 。源代码在GitHub上可供公众使用。

后台作业最佳做法的android官方文档 :帮助更好地了解意图服务,线程,处理程序,服务。以及执行网络操作


1
如果您能给出简短的答案,可能会更好。
eRaisedToX

12

我敢肯定,您可以通过简单地搜索“ Android IntentService vs Service”之类的内容找到大量差异

每个示例最重要的区别之一是IntentService完成后便会自行结束。

一些例子(迅速组成)可能是:

IntentService:如果要在打开应用程序开始时下载一堆图像。这是一次性的过程,一旦下载了所有内容,便可以自行清理。

服务:一种服务,将经常用于通过Web API调用在您的应用程序和后端之间进行通信。即使完成当前任务,您仍然希望它在几分钟后才能进行更多的交流。


2
我没有找到一个可以用一个例子做的例子,而不能用另一个例子做。只是一些对我没有帮助的解释。
roiberg 2013年

1
试试这个网站,它有不错的例子,对Android基本概念有很多很好的解释vogella.com/articles/AndroidServices/article.html
Stefan de Bruijn

4
它是“如何使用”的另一个示例。不是在专门使用服务和intentservice时。请给我一个理论上的例子,不要链接到该表的“如何使用”或任何其他样式。我不是要您为我“工作”,而是我什么也没做,只是我已经看到了所有这些喜欢的事,但仍不确定。
roiberg

5
这是非常重要的区别。例如,如果您使用服务来保持与服务器的持久连接,则不能使用intentservice,因为它在完成所有任务后立即终止
pelotasplus,2013年

24
当我用谷歌搜索时,它把我带到这里。现在我陷入无限循环。
Lou Morda 2014年

12

意图服务

IntentService在自己的线程上运行。完成后它将自行停止。更像是火与忘。随后的呼叫将排队。非常适合排队。IntentService如果需要,还可以在其中旋转多个线程-可以使用实现此目的ThreadPoolExecutor。我之所以这样说,是因为许多人问我“为什么使用IntentService它,因为它不支持并行执行”。 IntentService只是一个线程。您可以在其中执行所需的任何操作-甚至旋转多个线程。唯一的警告是,IntentService一旦旋转这些多线程,该操作就会结束。它不等待这些线程返回。您需要注意这一点。因此,我建议ThreadPoolExecutor在这些情况下使用。

  • 非常适合同步,上传等…

服务

默认Service情况下在主线程上运行。您需要旋转辅助线程来完成工作。您需要service明确停止。我将它用于需要在后台运行某些内容的情况下,即使您离开应用程序而返回更多内容以实现Headless service

  • 同样,如果需要,您可以运行多个线程。
  • 可以用于音乐播放器之类的应用。

您可以随时BroadcastReceivers根据需要与活动交流 。


8

IntentService是Service的扩展,旨在简化需要在后台和单独线程中执行的任务的执行。

IntentService启动,创建线程并在线程中运行其任务。一旦完成,它将清理所有内容。IntentService的一个实例只能同时运行,将多个调用排队。

它非常易于使用,并且对于许多用途(例如下载内容)非常方便。但是它有局限性,可能使您想使用更基本(而不是简单)的服务。

例如,连接到xmpp服务器并受活动限制的服务不能简单地使用IntentService来完成。您最终将忽略或覆盖IntentService。


看起来,大多数想在后台运行真正长期运行的服务的人最终都试图找到IntentService,因为文档使它看起来像是在这样做,但是您使用新的Thread还是一样好(新的Runnable())。start()。换句话说,当它谈到“产生一个新线程”时,它并不会将其移到一个单独的进程中,这实际上是大多数人想要从活动中分离出一些正在运行的代码时想要做的事情!(因为无论如何只是产生线程都是一个衬里)
Lassi Kinnunen 2014年

intentService还负责线程的生命周期,并使用循环程序,这有助于调度程序。它还可以确保仅一个实例在运行,并且将其他调用排队。
njzk2 2014年

5

如果有人可以向我展示一个示例,您可以使用an完成您的工作,IntentService而使用a service和其他操作则无法完成。

IntentService 不能用于长时间侦听,就像XMPP侦听器一样,它是一次性操作员,可以完成工作并挥手告别。

它也只有一个线程工作人员,但是有一个技巧,您可以将它用作无限个。


4

a Service和an 之间的主要区别IntentService如下:

服务内容:

1.A Service默认情况下在应用程序的主线程上运行(这里没有默认的工作线程),因此用户需要创建一个单独的线程并在该线程中执行所需的工作。

2,一次允许多个请求(多线程)

IntentService:

1.现在,来到IntentService,这里有一个默认的工作线程可以执行任何操作。注意 -您需要实现onHandleIntent()方法,该方法接收每个启动请求的意图,您可以在其中进行后台工作。

2.但是一次只允许一个请求。


3

Android IntentService与服务

1.服务

  • 使用startService()调用服务。
  • 可以从任何线程调用服务。
  • 默认情况下,服务在应用程序的主线程上运行后台操作。因此,它可以阻止您的应用程序的UI。
  • 多次调用的Service将创建多个实例。
  • 需要使用stopSelf()或stopService()停止服务。
  • Android服务可以运行并行操作。

2. IntentService

  • 使用Intent调用IntentService。
  • IntentService只能从Main线程中调用。
  • IntentService创建一个单独的工作线程来运行后台操作。
  • 多次调用的IntentService不会创建多个实例。
  • 队列完成后,IntentService自动停止。无需触发stopService()或stopSelf()。
  • 在IntentService中,多个intent调用会自动排队,并且将按顺序执行。
  • IntentService不能像Service一样运行并行操作。

这里参考

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.