Android中的Service与Thread有何区别?

37

我正在寻找应该在Android应用程序中使用的服务。

文档说明:

服务是一种应用程序组件,可以在后台执行长时间运行的操作,并且不提供用户界面。

我已经阅读了这篇帖子Application threads vs Service threads,它说同样的服务是用于在后台运行操作的。

但是这也可以使用Thread完成。 它们之间有什么区别,以及何时应该使用它们?


2
在使用线程和服务时,永远不会有选择的余地,因为它们是独立的问题,必须分别回答。 - Chris Stratton
4
@ChrisStratton,请您适当地书写您的回答。 - N Sharma
1
补充我之前的评论,虽然线程和服务的概念通常是正交的,但IntentService类代表了这两个想法的一种组合。 - Chris Stratton
1
可能是应用程序线程与服务线程的重复问题。 - Ciro Santilli OurBigBook.com
5个回答

41

根据最新文档更新:

Android在其文档中提到了何时应该使用Service和Thread。以下是文档内容:

如果您需要在主线程外执行工作,但仅在用户与您的应用程序交互时执行,则应创建一个新线程而不是服务。例如,如果您想播放一些音乐,但仅在运行您的活动时,您可以在onCreate()中创建一个线程,在onStart()中开始运行它,然后在onStop()中停止它。还应考虑使用AsyncTask或HandlerThread,而不是传统的Thread类。有关线程的更多信息,请参阅进程和线程文档。

请记住,如果确实使用服务,则默认情况下仍在应用程序的主线程中运行,因此如果服务执行密集或阻塞操作,则仍应在服务内部创建新线程。

这两种方法之间的另一个显着区别是,如果设备休眠,Thread将会休眠。而Service可以在设备进入睡眠模式时执行操作。让我们以使用这两种方法播放音乐为例。

Thread方法:仅当您的应用程序处于活动状态或屏幕显示时,音乐才会播放。

Service方法:即使您最小化应用程序或屏幕关闭,音乐仍可以播放。

注意:从API级别23开始,您应该测试Doze功能

Android文档 - 服务


1
作为这些信息的补充,请阅读https://dev59.com/bmUp5IYBdhLWcg3wGEgR。 - Eduardo Pinheiro
4
请注意,正如第一篇帖子所解释的那样,服务不在单独的线程中运行,这意味着如果您进行密集的CPU工作,它可能会阻塞主线程。阅读此帖子以获取更多信息:https://dev59.com/9Gsz5IYBdhLWcg3weHqU - Eduardo Pinheiro
2
请在Further Reading注释中添加解释此内容的Google文档的确切页面链接。 - Khay
这两种方法之间的另一个显著区别是,如果您的设备休眠,线程将会休眠。而服务可以在设备进入睡眠状态时执行操作。然而,服务无法在设备休眠时执行操作。https://dev59.com/JVUK5IYBdhLWcg3wqRhn#51587562 - Nick
你的答案已被编辑,因为它可能会误导一些人。 - Nick
显示剩余7条评论

29

服务(Service)是指独立于 Activity 运行任务的机制,它允许你在后台运行任何任务。但这会在主 UI 线程上运行,因此当你想进行网络或重负载操作时,就需要使用 Thread

例如:如果你想要每天在后台备份即时消息,那么你可以使用Service

线程(Thread) 是指在其自己的线程中运行任务而不是在主 UI 线程中运行。当你想进行一些重型网络操作,如持续向服务器发送数据时,就需要使用它,并且与 Android 组件相关联。当启动线程的组件被销毁时,你应该停止线程。

例如:你正在 Activity 中使用 Thread 进行某些操作,当你的 Activity 销毁时最好停止它。


2
但是假设你想播放音乐。那将是一些在后台/独立于任何活动的东西,所以你会使用一个服务对吧?但是你不能也启动一个线程来播放音乐而不使用服务吗? - committedandroider
1
我们知道,如果您不在活动中协调线程的生命周期,线程可能会导致活动泄漏。这意味着当活动被销毁时,如果线程的任务尚未完成,则线程仍然处于活动状态。因此,我认为线程与活动是独立的。 - Allen Vork
2
@committedandroider 如果你想在应用程序后台播放音乐,你可以使用线程,但不建议这样做,因为当设备屏幕关闭时,应用程序线程也会停止,从而停止音乐播放。相反,你可以创建一个Service并在其中使用工作线程,或者简单地选择IntentService,它是一个带有工作线程的Service。 - CopsOnRoad
1
抱歉打扰您。但是,我不理解“在后台运行任何任务”的意思。您能详细解释一下吗?我认为在后台运行意味着在不同的线程上运行。 - Trần Đức Tâm
1
@TrầnĐứcTâm “在后台运行任何任务”有两种理解方式。第一种是指在主线程中运行,但不显示 UI,例如 Service 在默认启动时的行为。第二种是在后台线程中运行。 - Albert Khang

11

这是我大多数遵循的原则

当操作发生时,如果需要应用程序可见,请使用线程。

  • 后台操作相对较短(少于一两分钟)
  • 活动/屏幕/应用程序与后台操作高度耦合,用户通常在此操作完成之前等待,在这些情况下使用线程可以产生更清晰、更易读和更易维护的代码。也可以使用Service(或IntentService)。

当操作发生时,如果应用程序可能不可见,请使用Service。

  • 功能如前台服务可帮助处理中断操作
  • 用户无需等待操作完成即可在应用程序中执行其他操作。
  • 应用程序可见性与操作无关。

如果你正在播放音乐,你会使用一个线程吗?因为这取决于你正在进行的活动——启动画面等。 - committedandroider
1
音乐从启动画面开始并结束?线程,是的。即使是主线程也可以,除非你正在远程流媒体(这对于持续2-3秒的启动画面来说可能不是一个好主意,因为流媒体可能需要更长时间才能开始)。 - Vinay W
那么服务就像 Spotify 一样,当您继续流式传输音乐而不与 UI 进行交互时? - committedandroider
2
正确。如果您想要实现这个目标,您应该使用一个服务。 - Vinay W

2

参考自https://developer.android.com/guide/components/services.html

服务是一种组件,即使用户不与您的应用程序交互,它也可以在后台运行。因此,只有在需要时才应创建服务。

如果您需要在主线程之外执行工作,但仅在用户与您的应用程序交互时执行,则可能应该创建一个新线程,而不是服务。

例如,如果您想播放音乐,但仅在您的活动正在运行时播放,您可以在onCreate()中创建一个线程,在onStart()中开始运行它,然后在onStop()中停止它。

请记住,如果您确实使用了服务,默认情况下它仍在应用程序的主线程中运行,因此如果它执行密集或阻塞操作,则仍应在服务内创建一个新线程。


0

我解释的方式很简单:

  1. 当您在活动中并希望进行一些与主线程频繁通信的后台操作时,请创建线程。 提示- 不要创建太多线程,因为1个线程等于1个处理器线程。如果想使用线程(多个)进行并行处理,请尝试使用Executors。

  2. 现在您需要长时间运行的操作并且与UI交互较少,则选择服务。请记住,服务在UI线程上运行。但是,现在您希望处理应在后台线程中完成,然后请使用Intent Service。Intent服务维护其线程池,不会创建新线程,并按顺序运行您的任务。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接