Asynctask vs Thread vs Services vs Loader

时间:2014-07-09 10:40:08

标签: android multithreading android-asynctask android-service

我对Android中AsynctaskThreadServiceLoader之间的差异感到有些困惑。

我知道它是如何运作的。但我仍然不明白我应该使用什么以及何时使用。

我使用Android工作了3年,并且通常仍然使用AsyncTask来执行所有后台任务(有时候是Thread)。但很多人都说'Asynctask已经过时了'#34;并且不建议使用它们。他们也建议使用robospice或Volley。

那么,AsyncTask真的如此糟糕,我应该使用框架进行网络任务吗?我应该将什么用于后台(而不是网络)任务?

6 个答案:

答案 0 :(得分:25)

线程:与Java线程相同,使用它来执行繁重的操作但是你必须自己管理它,它也可能导致同步问题,你不能从它更新UI,直到你在它上面运行它UI线程。

AsyncTask:Android中可用于执行后台任务的强大线程库。它由Android操作系统本身管理,您可以从中更新UI。它根据android的版本并行或串行运行。在方向更改的情况下,有时使用它可能会很麻烦,现在为了进行网络调用,您可以使用优于AsyncTask的排球。 AsyncTasks不关心他们的父活动是否正在运行,有时取消它可能会非常繁琐。所以,如果您使用AsyncTask进行休息API调用,请更好地使用RETROFITVOLLEY,如果您选择两者之间的RETROFIT,我建议您查看{{3}来自广场的另一个令人敬畏的图像用于图像加载。

服务:对于长期后台任务,您应该使用服务。如果需要,您可以将服务绑定到您的活动。您可以定义它们在同一个线程或不同的线程中运行,您需要在清单中声明它,或者您可以使用IntentService - 一个服务的变体,它在自己的线程中运行但在使用之前要小心,不要#39; t用于长时间运行的任务。它是一次性操作员。如果您打算使用服务,请评估适合您要求的情况,更好的是正常服务或IntentService

加载器:这在很多方面与AsyncTask相同,建议使用带有碎片的加载器,它解决了asynctasks的方向问题。

如果您已经转移到kotlin,我建议您查看PICASSO。这些非常轻量级,对线程非常有效,并为您提供对生命周期的大量控制。 我希望这会有所帮助。

答案 1 :(得分:19)

AysncTasks并非“过时”,因为它们不完整。 除其他事项外,如果父活动当前正在运行,则异步任务不会受到影响。出于同样的原因,您可以包含检查以验证上下文是否为空。此外,除非您使用自己的线程池执行程序,否则这些任务将以串行方式执行。

Volley试图填补这些空白,主要是关于与主线程和线程池的同步。如果您希望执行需要平均网络请求的内容,它会表现得最佳;比如一些元数据列表和图像(图片是youtube app请求和facebook app发帖的请求)。

Volley的一些优点通常如下

  1. 它使工作线程了解活动(主线程)
  2. 更轻松的资源优先级,您可以优先处理下载请求。 典型情况是您优先考虑文本而不是图像。
  3. 有效的请求缓存和内存管理。
  4. 可扩展
  5. 如果您的活动已关闭或重新启动,它会为您提供丢弃请求的选项。
  6. 与AsyncTasks相比,数据检索的模式更简单。
  7. 在Google I / O中提到的流式传输请求/视频时,Volley的表现非常糟糕。

    我并不完全了解robospice。 Ps:如果你有时间,请看https://www.youtube.com/watch?v=yhv8l9F44qo

    如果您希望进入具有相同基准的其他库,可以进一步阅读。 Comparison of Android networking libraries: OkHTTP, Retrofit, and Volley

答案 2 :(得分:4)

真正重要的是,你使用什么抽象,归结为Thread。因此,每个Android的异步/并行类都在幕后使用Thread / Executor,并且具有完全相同的潜在问题,例如线程所具有的锁定。

之间的区别在于它的'用法。例如,AsyncTask定义了一个方便的完成回调 - onPostExecute()CountDownTimer允许您控制时间等。

当然,您可以使用普通Thread,但在这种情况下,您需要投入更多时间自行解决可能出现的问题。

因此,Android为您提供了几种适合正确工作的合适工具。

答案 3 :(得分:3)

  

但许多人说“Asynctask已经过时”,不建议使用它们。

我没有遇到过这样说的人。但是,Android团队的工作是决定框架的某些部分何时过时或弃用。 CursorLoaders使用使用AsyncTaskLoader的{​​{1}}。 AsyncTask是一种抽象,可以防止开发人员必须实现令人讨厌的AsyncTasks状态逻辑。这意味着所有这些类在后台使用Thread

  

所以,Asynctask真的很糟糕,我应该使用框架   网络任务?我应该用什么背景(不是   网络)任务?

了解何时以及如何使用您的工具。你提到Threads。在这种特殊情况下,当您阅读文档并稍微使用它时,您会意识到它有意与CursorLoader平滑地集成。现在,ContentProviders抽象出基础数据;您可以查询本地SQLite数据库或远程服务器。

通常,ContentProviders用于检索“不太大”信息的简洁部分(用于与服务器通信时)。人们可能会说AsyncTasks已过时,因为有更好(更有效)的方式与服务器进行交互(请参阅Retrofit)。

答案 4 :(得分:2)

我认为AsyncTask优于Thread,因为它在主线程上提供回调。 Loader优于AsyncTask,因为它还会为您处理配置更改。

答案 5 :(得分:2)

AsyncTask

  

AsyncTask可以正确,轻松地使用UI线程。此类允许您执行后台操作并在UI线程上发布结果,而无需操作线程和/或处理程序。

AsyncTask旨在成为Thread和Handler的辅助类,并不构成通用的线程框架。理想情况下,AsyncTasks应该用于短期操作(最多 几秒 。)

如果您需要长时间保持线程运行,强烈建议您使用java.util.concurrent包提供的各种API,例如ExecutorThreadPoolExecutor和{{ 1}}。

Thread

  

从主线程中移动大量或长期任务,以便它们不会干扰平滑渲染和对用户输入的快速响应,这是您在应用中采用线程的最大原因。

使用它将长时间运行的计算与主线程(UI线程)分开

Service

  

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

服务可以从后台处理 网络交易,播放音乐,执行文件I / O或与内容提供商进行交互

IntentService

  

IntentService是服务的基类,可根据需要处理异步请求(表示为Intents)。

所有请求都在一个工作线程上处理 - 它们可能需要多长时间(并且不会阻止应用程序的主循环), 但是只会处理一个请求一段时间。

Loader

  

Loader API允许您从内容提供商或其他数据源加载数据,以便在活动或片段中显示。

装载机解决了这些问题并包含其他好处。例如:

  1. 加载程序在不同的线程上运行,以防止janky或无响应的UI。

  2. 加载程序通过在事件发生时提供回调方法来简化线程管理。

  3. 加载程序会在配置更改中保持并缓存结果,以防止重复查询。
  4. 加载程序可以实现观察者来监视基础数据源的更改
  5.   

    那么,Asynctask是非常糟糕的,我应该使用框架进行网络任务?我应该将什么用于后台(而不是网络)任务?

    使用FutureTask处理持续时间小于5毫秒的工作项。您可以使用AsyncTaskThreadService作为后台任务。