Asynctask vs Thread vs Services vs Loader

我对Android中的AsynctaskThreadServiceLoader之间的区别感到有些困惑。

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

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

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

Solutions Collecting From Web of "Asynctask vs Thread vs Services vs Loader"

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

Volley试图填补这些空白,主要涉及与主线程和线程池的同步。 如果您希望执行需要平均网络请求的内容,它会表现最佳; 像一些元数据列表和图像(图片youtube应用程序请求和Facebook应用程序请求的post)。

通常,Volley的几个优点如下

  1. 它使工作线程了解活动(主线程)
  2. 更轻松的资源优先级,您可以优先处理下载请求。 典型情况是您优先考虑文本而不是图像。
  3. 有效的请求缓存和内存管理。
  4. 扩展
  5. 它为您提供了一个选项,可以在您的活动关闭或重新启动时丢弃您的请求。
  6. 与AsyncTasks相比,数据检索的模式更简单。

在Google I / O中提到的流式传输请求/video时,Volley的表现非常糟糕。

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

如果您希望进入其他具有相同基准的库,可以进一步阅读。 Android网络库的比较:OkHTTP,Retrofit和Volley

线程:与Java线程相同,使用它来执行繁重的操作,但是您必须自己管理它,它还可能导致同步问题,并且在UI线程上运行UI之前无法更新UI。

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

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

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

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

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

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

当然,您可以使用普通的Thread ,但在这种情况下,您必须花更多的时间自己捕捉可能出现的问题。

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

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

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

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

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

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

AsyncTask :

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

AsyncTask被设计为围绕Thread和Handler的助手类,并不构成通用的线程框架。 理想情况下, AsyncTasks应该用于短操作( 最多几秒钟 )。

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

线程 :

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

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

服务 :

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

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

IntentService :

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

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

装载机 :

Loader API允许您从内容提供程序或其他数据源加载数据,以便在Activity或Fragment中显示。

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

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

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

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

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

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

我认为AsyncTaskThread更好,因为它在主线程上提供回调。 LoaderAsyncTask更好,因为它还可以为您处理配置更改。