为什么我在这里阅读大多数问题的答案很多关于 AsyncTask和装载机,但没有关于 服务?服务是否只是不太了解,或者它们已经过时,或者有一些不好的属性或者其他什么?有什么区别吗?
AsyncTask
(顺便说一下,我知道还有其他关于它的线程,但没有一个真正说明明确的区别,以帮助开发人员轻松地决定是否应该使用其中一个或另一个来解决实际问题。)
服务 是完全不同的: 服务不是 线程!
您的 Activity 绑定到一个服务,该服务包含一些在调用时阻塞调用线程的函数。您的服务可能用于将温度从摄氏度更改为度数。任何绑定的活动都可以获得此服务。
但是,AsyncTask是一个线程,它在后台执行一些工作,同时能够将结果报告给调用线程。
只是一个想法: 一个 < em > 服务 可能有一个 < em > AsyncTask 对象!
在某些情况下,使用 AsyncTask或者 Service完成同样的任务是可能的,但是通常情况下,其中一个比另一个更适合于一个任务。
Service
AsyncTask是为一次性耗时的任务而设计的,这些任务不能在 UI 线程中运行。一个常见的例子是按下按钮时获取/处理数据。
Service被设计为在后台连续运行。在上面按下按钮时获取数据的示例中,您可以启动一个服务,让它获取数据,然后停止它,但这是低效的。使用将运行一次、返回数据并完成操作的 AsyncTask要快得多。
但是,如果您需要在后台不断地做一些事情,那么 Service是您最好的选择。这方面的例子包括播放音乐,不断检查新数据等等。
另外,正如 Sherif 已经说过的,服务不一定在 UI 线程之外运行。
大多数情况下,即使应用程序的 Activity没有打开,Service也是用来运行代码的。AsyncTask的设计目的是使 UI 线程的执行代码非常简单。
Activity
Service是 Android 框架的组件之一,它不需要 UI 来执行,这意味着即使用户不主动使用应用程序,您也可以使用服务执行某些操作。这并不意味着服务将在单独的线程中运行,而是在主线程中运行,并且在需要时可以在单独的线程中执行操作。 例如,在后台播放音乐,在没有用户交互的情况下与后台服务器同步数据等
另一方面,AsyncTask用于在单独的线程上执行 UI 阻塞任务。这与创建一个新线程并在 AsyncTask 负责创建和维护线程以及将结果发送回主线程的所有任务时执行该任务是一样的 例如从服务器获取数据,内容解析器上的 CRUD 操作等
Service 和 异步任务几乎在做同样的事情,差不多。使用服务或异步任务取决于您的需求是什么。
作为一个例子,如果你想从服务器加载数据到一个列表视图后,点击一些按钮或改变屏幕,你最好去与一个异步任务。它运行与主 UI 线程并行(运行在后台)。或者你的应用程序应该在主 UI thread.after 退出应用程序后没有异步任务。
但是服务不是这样的,一旦你启动一个服务,它可以在你退出应用程序后运行,除非你停止服务。就像我说的那样,这取决于你的需求。如果你想继续检查数据接收或者不断检查网络状态,你最好选择服务。
编程愉快。
在少数情况下,您可以同时使用两者来实现相同的功能。与异步任务不同,服务有自己的生命周期并继承上下文(服务比异步任务更健壮)。服务可以运行,即使你退出了应用程序。如果你想做一些甚至在应用程序关闭后,也需要上下文变量,你会去服务。
例如: 如果你想播放音乐,并且不想在用户离开应用程序时暂停,你肯定会选择 Service。
本地、进程内、基类服务 something 与 AsyncTask的比较:
Something (这个答案并不涉及导出的服务,也不涉及运行在与客户端不同的流程中的任何服务,因为预期的用例与 AsyncTask的用例大不相同。另外,为了简洁起见,这里将忽略某些特定的 Service子类(例如,IntentService,JobService)的性质
IntentService
JobService
过程生命周期
对于操作系统来说,Service表示“应用程序希望在不与用户交互的情况下执行较长时间的操作”[ 裁判]。
当你运行 Service的时候,Android 明白你不希望你的进程被终止。当屏幕上有 Activity时也是如此,当运行 前台服务时尤其如此。(当所有的 应用程序组件都离开时,Android 会想,“哦,现在是关闭这个应用程序的好时机,这样我就可以释放资源了”。)
此外,根据从 Service.onCreate()返回的最后值,Android 可以尝试“重启”由于资源压力而被关闭的应用程序/服务[ 裁判]。
Service.onCreate()
AsyncTasks不会这么做。不管你运行了多少后台线程,也不管它们有多难运行: Android 不会仅仅因为你的应用在使用 CPU 而让你的应用保持活跃。它必须有一些 知道的方式,你的应用程序仍然有工作要做; 这就是为什么 Services是注册在操作系统,而 AsyncTasks没有。
AsyncTasks
Services
多线程
AsyncTasks完全是关于创建一个后台线程来进行工作,然后以线程安全的方式将工作结果呈现给 UI 线程。
每次新的 AsyncTask执行通常会导致更多的并发性(更多的线程) ,这取决于 AsyncTasks's线程池[ 裁判]的限制。
AsyncTasks's
另一方面,Service方法是 始终在 UI 线程上调用[ 裁判]。这适用于 onCreate()、 onStartCommand()、 onDestroy()、 onServiceConnected()等。因此,在某种意义上,Services不“运行”在后台。一旦他们启动(onCreate()) ,他们只是有点“坐”在那里-直到它的时间清理,执行一个 onStartCommand(),等等。
onCreate()
onStartCommand()
onDestroy()
onServiceConnected()
换句话说,添加额外的 Services并不会导致更多的并发性。服务方法不是做大量工作的好地方,因为 它们在 UI 线程上运行。
当然,您可以扩展 Service,添加您自己的方法,并从您想要的任何线程调用它们。但是如果您这样做了,那么线程安全的责任就落在了您的身上——而不是框架。
如果您想在 Service中添加一个后台线程(或其他类型的辅助线程) ,您可以自由地这样做。例如,可以在 Service.onCreate()中启动一个后台线程/AsyncTask。但并非所有用例都需要这样做。例如:
Activities
BroadcastReceiver
这两种用例都不需要大量的 CPU 活动; 它们只需要应用程序 而不是被杀。
作为工人
Services不是面向任务的。它们不像 AsyncTasks那样被设置为“执行任务”和“交付结果”。Services不能解决任何线程安全问题(尽管所有方法都在一个线程上执行)。另一方面,AsyncTasks为您处理这种复杂性。
请注意,AsyncTask是 被认为是不赞成的。但是这并不意味着你应该用 Services代替你的 AsyncTasks!(如果你从这个答案中学到了什么,这一点应该很清楚。)
DR
Services主要是为了“存在”而存在的。它们就像屏幕外的 Activity,为应用程序提供了一个保持活力的理由,而其他组件负责做“工作”。AsyncTasks做“工作”,但它们本身不会使进程保持活跃。