服务、异步任务和线程之间的区别是什么?

151

Service、异步任务和线程之间有什么区别?如果我没记错的话,它们都用于在后台执行一些任务。那么,如何决定在哪种情况下使用哪种方式呢?


似乎还有一个常常会让人们感到困惑的东西 - 加载器。相关主题 - Asynctask vs Thread vs Services vs Loader - RBT
6个回答

190

也许你已经读过有关它们的文档描述,我不会重复,相反我将用自己的话来回答,希望能帮到你。

  • Service类似于Activity但没有用户界面。如果你想要获取天气信息,你不必为此创建一个空白的Activity,而是可以使用Service。

  • Thread是线程,也许你已经从其他地方了解过了。你需要知道,你不能从一个Thread中更新UI。你需要使用Handler来完成这个任务,但请继续阅读。

  • AsyncTask是一种智能线程,建议使用。它很智能,因为它可以通过其方法帮助你完成任务,而且有三个方法在UI线程上运行,特别适合更新UI组件。

我经常使用Service和AsyncTask,较少或根本不使用Thread,因为几乎可以用AsyncTask完成所有任务。


1
谢谢您的解释。那么,如果我需要制作一个从网络获取数据的应用程序,使用服务还是异步任务会更好呢? - SpunkerBaba
17
需要同时使用两者。您需要创建一个服务,并在其中使用AsyncTask。 - Pentium10
4
除了上面的答案之外,AsyncTask通过onPreExecute(),onProgressUpdate(Progress ...),onPostExecute(Result){在UI线程运行} 这4个步骤,并通过doInBackground(Params ...){在后台线程运行} 。由于它在UI线程中提供了3种方法,因此用户无需担心使用处理程序或回调来更新UI。 - SpunkerBaba
11
@Pentium10 :与其使用Service+AsyncTask,你通常可以使用IntentService。 - njzk2
11
值得注意的是,默认情况下,Android服务在主线程(UI线程)上运行。如果您的服务需要在后台执行工作,则需要显式地在单独的线程(或AsyncTask)中启动它。否则,它可能会影响UI的响应性并引发“应用程序未响应”错误。就Android而言,服务本质上是一个“不可见”的和“微小的”Activity,不一定是一个“后台”工作程序。 - CCJ
显示剩余3条评论

25

这是你问题的最简单答案

线程

是一种在主线程“并行”运行的执行单元,这是一个重要的观点,除了主线程之外,在此任何线程都不能更新UI组件。

AsyncTask

是一个特殊的线程,它提供了更新UI的辅助方法,因此基本上你可以在后台线程上运行AsyncTask,同时更新UI。不需要显式处理进程间通信。

Service

解决了上述问题,因为它与调用它的活动分离,所以即使活动被销毁,它也可以继续运行它在主线程中运行(注意ANR),使用后台服务(扩展IntentService会自动为您创建工作线程)服务类似于没有UI的活动,适合长时间任务。


4
AyncTask不会在旋转设备时重新创建,因为它与Activity生命周期方法不同步。 - CopsOnRoad
4
您在Activity生命周期中创建了AsyncTask,在旋转手机时,Activity会被销毁并重新启动。先前的AsyncTask实例与您刚刚销毁的Activity相连,因此您将会收到“强制关闭”的提示,但同时您也会看到一个新的AsyncTask实例正在触发。您可以使用Fragments来保留AsyncTask,并在该Fragment上设置setRetainInstance(true)属性以帮助您解决这个问题。 - Alejandro Serret

15

以下是我希望几天前有人告诉我的一些重要信息:

  • 您可以在活动(Activities)和服务(Services)之间共享全局变量,例如线程。
  • 只要还有活动(Activity)或服务(Service)存在,您的应用程序及其所有全局变量都不会被清除。
  • 如果您在应用程序中有一个服务(Service)实例并且操作系统需要资源,它将首先终止您的活动(Activity),但只要还有服务(Service)存在,操作系统就不会清除您的应用程序以及其全局变量。

我的用例如下:我在全局空间中有一个连接到服务器的线程和一个显示结果的活动(Activity)。当用户按下主页键时,该活动(Activity)进入后台并启动一个新服务(Service)。然后,该服务从线程读取结果,并在需要时在通知区域显示信息。我不必担心操作系统销毁我的活动(Activity),因为我知道只要服务(Service)在运行,它就不会销毁线程。


10

简而言之,服务(Service) 用于处理 耗时任务异步任务(AsyncTask) 用于处理 短时间任务线程(Thread) 是 Java 的一个 标准工具类,用于线程处理。


4

从开发者的角度来看:

线程:用于并行执行一组代码,但您不能在线程内处理UI。为此,您需要使用HandlerHadler将线程RunnableLooper绑定,使其成为UI线程。

ASyncTask:用于处理那些无法在主线程上工作的任务。例如,HTTP请求是一个非常繁重的工作,无法在主线程上处理,因此您可以在ASyncTask中处理HTTP请求。它在后台与主线程异步并行工作。它有一些回调方法,在相应的事件上被调用。

服务:在同一Application进程下后台工作。当您必须进行某些处理而没有任何与之关联的UI时,实现此功能。


1
除非您使用IntentService,否则“服务”不一定会在后台运行。如果您从UiThread启动了一个标准的“服务”,它将在UiThread上运行。 - yshahak
@yshahak 您是正确的,但在这里我们不需要深入定义。用户只想知道它们之间的区别。 - Rahul Raina
是的,但这并不准确,因为默认情况下Service不会在不同的进程中运行,而是在应用程序进程中与其他组件一起运行。更好的说法是Service将在其所在的线程的后台运行。 - yshahak
以上三种方法都在应用程序进程中运行。ASyncTask的preExecute()和postExecute()方法在UI线程上运行,而doInBackground()和onProgress()方法在后台线程上运行。Service在后台线程上运行,Thread也在后台线程上运行。然而,Handler在UI线程上运行。 - Rahul Raina

2

服务就像是一个耗时的活动,但异步任务允许我们执行长时间/后台操作,并在UI线程上显示其结果,而无需操纵线程。


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