Android:AsyncTask与服务


138

为什么我在这里阅读有关大多数问题的答案,而有关AsyncTaskLoader的却很多,而对Services却一无所知?是不是只是对服务的了解不是很好,还是不赞成使用它们或它们具有某些不良属性或某些东西?有什么区别?

(顺便说一句,我知道还有其他线程,但是没有人真正指出明显的差异,这些差异可以帮助开发人员轻松地确定自己是否更适合使用一个或另一个解决实际问题。)

Answers:


272

在某些情况下,可以用一个AsyncTask或多个来完成相同的任务,Service但是通常一个比另一个更适合于一项任务。

AsyncTasks专为无法运行UI线程的一次性耗时任务而设计。一个常见的示例是按下按钮时获取/处理数据。

Services旨在在后台连续运行。在上面的示例中,当按下按钮时获取数据的示例中,您可以启动服务,让它获取数据,然后停止它,但这效率很低。使用一次AsyncTask将运行一次,返回数据并完成的速度要快得多。

但是,如果您需要在后台不断地做某事,那么a Service是最好的选择。例如,播放音乐,不断检查新数据等。

而且,正如Sherif所说,服务不一定要从UI线程中运行。

在大多数情况下,Services用于即使您的应用程序Activity未打开也要运行代码的情况。AsyncTask旨在使从UI线程执行代码非常简单。


2
有趣的是,在2010年Google I / O 的演讲youtube.com/watch?v=xHXn3Kg2IQE中,演示者提供了3种不同的方法来从REST API获取数据,第一种方法使用服务。我不是Android专家,但也给我留下了印象,Computerish所说的基本上是正确的。
wuliwong 2012年

10
最后一个段落,“服务是为即使您的应用程序的“活动”未打开时也要运行代码的用户提供的”。AsyncTask或后台线程也是如此。例如,当您按回活动或调用finish()时,您的活动不可见,但后台线程仍在执行,直到您终止应用程序进程为止(例如,通过交换最近的任务)。我曾与4.4.2谷歌Nexus AOSP石斑鱼选中此
希里什Herwade

10
但是,如果启动AsyncTask的活动在AsyncTask仍在运行时被杀死,并且一旦完成就需要更新UI,则AsyncTask可能会很棘手(因为Activity已被销毁,因此将无法工作)。为什么不使用IntentService,因为它一旦完成便会结束,您无需手动停止该afaik?
AgentKnopf

很棒的要点,关于服务的很好的解释。那就是即使工作完成,服务也会在后台连续运行。
BABU K 2014年

3
@LarsH如果我错了,请纠正我,但是我认为您可以在Activity / Fragment中使用BroadcastReceiver,一旦完成,您就可以从IntentService中触发Broadcast。由于您可以根据活动/片段的重新创建来重新注册广播,因此您应该了解一下。另一个替代方法是使用EventBus来更新UI(尽管我尽量避免使用这些代码-使得代码难以遵循imo)。
AgentKnopf

58

服务完全不同:服务不是线程

您的活动绑定到服务,并且该服务包含一些函数,这些函数在被调用时会阻止调用线程。您的服务可能用于将温度从摄氏度更改为摄氏度。任何绑定的活动都可以获取此服务。


但是AsyncTask,一个Thread在后台执行某些工作,同时具有将结果报告回调用线程的能力。

只是一个想法:服务可能有AsyncTask对象!


2
服务被描述为在后台运行,即使关闭了您的应用程序也继续运行。AsyncTask还用于在后台执行某些操作。明白我的意思了吗?
erikbwork 2011年

1
是的,但是服务可能会或可能不会在做某事。他们是一个持久的目标
Sherif elKhatib 2011年

“服务可能具有AsyncTask对象!” 感谢您指出了这一点。但这是一个好主意-您会推荐它吗?还是在服务中使用更多基本的线程技术会更好?
RenniePet

不一定是“您的活动绑定到服务”。
JacksOnF1re

@ JacksOnF1re我知道这就像我刚开始编码:p时一样,但是“您的活动绑定到服务”是真实的声明。我也可以绑定到此服务。冰箱也可以装订。这不会使该语句无效。.无论如何,jk
Sherif elKhatib 2015年

7

Service是Android框架的组件之一,不需要执行UI,这意味着即使用户未积极使用该应用,您也可以通过服务执行某些操作。这并不意味着服务将在单独的线程中运行,而是在主线程中运行,并且可以在需要时在单独的线程中执行操作。示例用法是在后台播放音乐,在后台与服务器同步数据而无需用户交互等

AsyncTask另一方面,UI阻止任务用于在单独的线程上执行。当AsyncTask负责创建和维护线程以及将结果发送回主线程的所有任务时,就像创建一个新线程并执行任务一样,示例用法是从服务器获取数据,内容解析器上的CRUD操作等。


您能指定为什么您认为自己的答案对问题有帮助吗?
erikbwork

2
其他答案对于初学者来说太短或太长。所以我用示例简单地回答了这个问题
arjun

6

服务异步任务几乎在做同一件事,几乎使用服务还是异步任务取决于您的需求。

例如,如果要在单击某些按钮或更改屏幕后从服务器将数据加载到列表视图,则最好使用asynctask。它与主ui线程并行运行(在后台运行)。对于运行asynctack活动或您的应用程序应该在主UI线程上。从应用程序退出后,没有asynctask。

但是服务不是那样的,一旦启动一项服务,它就可以在退出应用程序后运行,除非您停止该服务。就像我说的那样,这取决于您的要求。如果要继续检查数据接收或检查网络状态持续地,您最好选择服务。

快乐的编码。


1
嗨,Ashana,我能问一下您为什么对已经回答的问题提供此答案吗?您对现有的标记答案感到不满意吗?还是您要通过对所有要说的问题写您的意见来尝试建立SO概要?还是完全不同的东西?无法弄清楚,但最近我经常看到这种模式。
erikbwork

3
是的,我知道答案已经给出,如果在这里给我正确答案或我的意见,我在这里看不到太多问题?因为您不是唯一正在寻找同一问题答案的人,所以如果某人难以理解以上答案中的解决方案,他/她可以向下滚动以寻找适合他们的答案,轻松理解一个答案。感谢您的评论兄弟,我不是编程方面的天才还是专业人士,只想帮助他人,尝试教别人我已经知道的知识:)
Ashana.Jackol

1

在少数情况下,您可以同时使用两者实现相同的功能。与异步任务不同,服务具有其自己的生命周期并继承上下文(服务比异步任务更健壮)。即使您退出了应用程序,服务也可以运行。如果您想要在关闭应用程序后仍要执行某些操作,并且还需要context变量,则可以使用Service。

示例:如果您想播放音乐,并且不想在用户离开应用程序时暂停播放,那么您肯定会寻求服务。


1

一个比较本地,过程,基类服务 ✱到AsyncTask

✱(此答案未解决导出的服务或在与客户端不同的过程中运行的任何服务,因为预期的用例与客户端的用例大不相同AsyncTask。而且,为了简洁起见,某些专门工具的性质Service子类(例如IntentServiceJobService)将在这里被忽略了。)

工艺寿命

Service表示,到OS,[“应用程序的欲望而不是与用户的交互进行运行更长的操作” REF ]。

Service运行时,Android知道您不希望进程被杀死。每当有Activity屏幕显示时也是如此,尤其是在运行前台服务时。(当所有应用程序组件都消失时,Android会认为:“哦,现在是杀死该应用程序的好时机,因此我可以释放资源”。)

另外,根据的最后一个返回值Service.onCreate(),Android可以尝试“恢复”由于资源压力而被杀死的应用程序/服务[ ref ]。

AsyncTasks什么都不做。不管运行了多少后台线程,或者它们有多努力都没有关系:Android不会仅仅因为您的应用程序正在使用CPU来保持您的应用程序处于活动状态。它必须以某种方式知道您的应用程序仍有工作要做。这就是为什么Services要在OS中注册的原因,而AsyncTasks没有。

多线程

AsyncTasks 都是关于创建要在其上进行工作的后台线程,然后以线程安全的方式将该工作的结果呈现给UI线程。

每个新的AsyncTask执行通常会导致更多的并发(更多线程),但受AsyncTasks's线程池[ ref ] 的限制。

Service另一方面,方法总是在UI线程 [ ref ] 上调用。这适用于onCreate()onStartCommand()onDestroy()onServiceConnected(),等,所以,在某种意义上,Services在后台不“跑”。一旦启动(onCreate()),他们就可以“坐在”那里-直到该进行清理,执行onStartCommand()等等。

换句话说,添加其他内容Services不会导致更多的并发。服务方法不是执行大量工作的好地方,因为它们在UI线程上运行

当然,您可以扩展Service,添加自己的方法,然后从所需的任何线程调用它们。但是,如果这样做,线程安全的责任就在您自己身上,而不是框架。

如果您想在其中添加后台线程(或其他某种工作线程)Service,则可以这样做。你可以启动一个后台线程/ AsyncTaskService.onCreate(),例如。但并非所有用例都需要这样做。例如:

  • 您可能希望保持Service运行状态,以便可以继续在“后台”(意味着不必在Activities屏幕上显示)中获取位置更新。
  • 或者,您可能希望保持应用程序的运行状态,以便可以BroadcastReceiver长期注册“隐式” (在API 26之后,您不能始终通过清单执行此操作,因此必须在运行时注册) [ ref ])。

这些用例都不需要大量的CPU活动。他们只是要求不要杀死该应用程序。

作为工人

Services不是面向任务的。他们没有像那样AsyncTasks被设置为“执行任务”和“交付结果” 。Services不要解决任何线程安全问题(尽管所有方法都在单个线程上执行)。AsyncTasks另一方面,可以为您解决这种复杂性。

请注意,AsyncTask提名为弃用。但是,这并不意味着你应该更换你AsyncTasksServices!(如果您从此答案中学到了什么,那么应该很清楚。)

TL; DR

Services大多在那里“存在”。它们就像屏幕外Activity,为应用程序保持运行提供了理由,而其他组件则负责完成“工作”。AsyncTasks做“工作”,但他们本身并不会保持流程的活力。

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.