Android中的AsyncTask与线程


135

在UI中,为了执行一些后台工作,我使用了单独的Thread。但正如其他人所建议的,我现在正在使用AsyncTask

Thread和之间的主要区别是AsyncTask什么?

在哪种情况下,我应该使用a Thread还是AsyncTask



@ webaldo.at我回想了一下,在这里他们给了他们输入描述以及Asynctask和Thread之间的区别。
拉姆

缩短:线程->无法访问UI线程|| Asynctask->有条件地访问UI线程
JavaDM

用于后台任务IntentService是另一个不错的选择。

Answers:


146

对于长时间运行或占用大量CPU的任务,基本上有两种方法可以执行此操作:Java线程和Android的本地AsyncTask。

两者都不一定比另一个更好,但是知道何时使用每个呼叫对于利用系统性能以使您受益至关重要。

使用AsyncTask用于:

  1. 简单的网络操作,无需下载大量数据
  2. 磁盘绑定任务可能需要几毫秒的时间

将Java线程用于:

  1. 涉及中到大量数据的网络操作(上传或下载)
  2. 需要在后台运行的高CPU任务
  3. 您想要控制相对于GUI线程的CPU使用率的任何任务

互联网上有很多好的资源可以帮助您:

http://www.vogella.com/articles/AndroidBackgroundProcessing/article.html


请问为什么下载数据量有问题?

1
@Yeung似乎您需要有关异步任务的见解!看起来,数据量越大,那么显然完成相同操作所需的时间也就越大。因此,由于以下原因,使用Async Task进行长时间运行的过程不是一个好习惯:1. Async Task与Activity生命周期的联系很差。2.它们会造成内存泄漏。
Mohit


谢谢。我现在了解风险。

@Impasse @Yeung IMO的数据量不是问题,网络操作的关键问题在于操作时间。当服务器繁忙,无法访问(超时)等情况时,即使下载几个字节也可能需要很长时间。一种解决方法是可以AsyncTask与自己的调度程序一起使用。
xmedeko

44

如果使用Java线程,则必须在自己的代码中处理以下要求:

如果将结果回发到用户界面,则与主线程同步

取消线程没有默认设置

没有默认的线程池

没有默认值来处理Android中的配置更改


3
实际上,这更能说明问题,因为它解决了不使用简单线程的原因。在我的脑海中,任何需要与活动/服务生命周期相关联的事物都应该改用AsyncTask,即使您需要手动“优雅地降级”任务内部的资源,至少您最终也不会挂起任务当活动被杀死时。
leRobot

28

线

  • 一般 任务漫长
  • 通过thread.start()方法调用
  • 任何线程触发
  • 自己的线程上运行
  • 手动线程管理/代码可能变得难以阅读

异步任务

  • 必须与主线程通信的小任务
  • 通过excute()方法调用
  • 主线程触发
  • 工作线程上运行
  • 必须从主线程执行并创建

11

线

线程是并发执行单元。它有自己的调用堆栈。有两种方法可以在应用程序中实现线程。

一种是提供一个扩展Thread并覆盖其run()方法的新类。另一个是在创建新线程实例时为其提供一个Runnable对象。线程可以通过调用其“ start”方法来执行。您可以通过调用线程的“ setPriority(int)”方法来设置线程的“优先级”。

如果您对UI部分没有影响,则可以使用线程。例如,您正在调用某些Web服务或下载一些数据,并且在下载后,将其显示在屏幕上。然后,您需要使用带有线程的处理程序,这将使您的应用程序变得复杂,无法处理来自线程的所有响应。

处理程序使您可以发送和处理与线程的MessageQueue关联的Message和Runnable对象。每个线程都有每个消息队列。(类似于待办事项列表),线程将获取每条消息并对其进行处理,直到消息队列为空。因此,当处理程序进行通信时,它只会向调用方线程提供一条消息,并且它将等待处理。

如果使用Java线程,则需要在自己的代码中满足以下要求:

如果将结果回传到用户界面,则与主线程同步没有取消线程的默认值没有默认线程池的默认值处理Android中配置更改的默认值

异步任务

通过AsyncTask,可以正确,轻松地使用UI线程。此类允许执行后台操作并在UI线程上发布结果,而无需操纵线程和/或处理程序。异步任务由在后台线程上运行的计算定义,并且其结果发布在UI线程上。

AsyncTask将经历以下四个阶段:

onPreExecute()

在执行任务之前在UI线程上调用

doInbackground(Params ..)

onPreExecute()完成执行后立即在后台线程上调用。

onProgressUpdate(Progress ..)

调用publishProgress(Progress ...)后在UI线程上调用。

onPostExecute(结果)

后台计算完成后在UI线程上调用。

为什么要使用AsyncTask?

易于使用的UI线程。(因此,在调用者线程是UI线程时使用它)。

无需操纵处理程序。

欲了解更多信息,请点击这里


2

线:

Thread应该将长时间运行的操作与主线程分开,以提高性能。但是它不能被优雅地取消,并且不能处理Android的配置更改。您无法从更新UI Thread

AsyncTask可用于处理持续时间少于5毫秒的工作项目。使用AsyncTask,您可以更新与java不同的UI Thread。但是,许多长时间运行的任务会降低性能。

您没有更多选择可替代它们。

HandlerThread / 处理程序ThreadPoolExecutor

请参阅以下帖子以获取更多详细信息:

处理程序与AsyncTask与线程

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.