处理程序和AsyncTasks之间有所不同

时间:2015-01-20 06:24:38

标签: android

我需要在android中使用后台操作,所以我需要知道Android中处理程序和AsyncTask之间的区别是什么?

3 个答案:

答案 0 :(得分:0)

简单明了的答案如下

<强> AsynTask:

它提供了一个简单的线程实现,不知道任何关于java线程模型的信息,AsyncTask给出了工作线程和主线程的各种回调。

使用:用于小等待操作,如

从Web服务获取一些数据并在布局上显示。 数据库查询。 当你意识到运行操作永远不会 - 嵌套。

<强>处理程序

它也是实现java线程模型,它允许嵌套你运行操作,比如从互联网上获取多个图像。

最适合:

1允许消息排队。 2.消息调度。 3.多次长时间运行。

<强>发

现在是时候开始了。

线程是两者的父,AsyncTask在内部使用线程,这意味着您也可以像AsyncTask一样创建自己的胎面模型,而Handler实例与单个线程和该线程的消息队列相关联。它需要熟悉java多线程实现。

用途:

您可以执行AsyncTask和Handler可以执行的所有操作。

答案 1 :(得分:0)

文档说

处理程序

  • android.os.Handler

Handler允许您发送和处理与线程的MessageQueue 相关联的Message和Runnable对象。

每个Handler实例都与一个线程和该线程的消息队列相关联。

当你创建一个新的Handler时,它被绑定到正在创建它的线程的线程/消息队列 - 从那时起,它将消息和runnables传递给该消息队列并在它们出现时执行它们消息队列

Handler有两个主要用途:(1)安排消息,runnables将来作为某个点执行; (2)将要在不同于您自己的的线程上执行的操作排入队列。

使用post, postAtTime(Runnable, long), postDelayed, sendEmptyMessage, sendMessage, sendMessageAtTime, and sendMessageDelayed方法完成消息调度。

帖子版本允许您在收到消息队列时由将Runnable对象排队。 sendMessage版本允许您将包含将由Handler的handleMessage方法处理的数据包的Message对象排入队列(要求您实现Handler的子类)。

发布或发送给处理程序时,您可以在消息队列准备好后立即允许处理该项目,或者在处理之前指定延迟或处理它的绝对时间。

后两者允许您实现超时,滴答和其他基于时间的行为。

当为您的应用程序创建进程时,其主线程专用于运行消息队列,该队列负责管理顶级应用程序对象(活动,广播接收器等)以及它们创建的任何窗口。

您可以通过处理程序创建自己的线程,并与主应用程序线程进行通信

这是通过调用与以前相同的post或sendMessage方法完成的,但是来自新线程。

然后将在Handler的消息队列中安排给定的Runnable或消息并在适当的时候进行处理。


AsyncTask

  • android.os.AsyncTask

AsyncTask可以正确,轻松地使用UI线程。

此类允许执行后台操作并在UI 线程上发布结果,而无需操纵线程和/或处理程序

AsyncTask旨在成为Thread和Handler的辅助类,并不构成通用的线程框架

理想情况下,AsyncTasks应该用于进行短操作(最多只需几秒钟。)

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

异步任务由计算定义,该计算在后台线程上运行,其结果在UI 线程上发布。

异步任务由3种泛型类型定义,称为Params,Progress和Result,以及4个步骤,分别称为onPreExecute,doInBackground,onProgressUpdate和onPostExecute。

<强>用法

AsyncTask必须是子类才能使用。

子类将覆盖至少一个方法(doInBackground),并且通常会覆盖第二个方法(onPostExecute。)

以下是子类化的示例:

 private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
     protected Long doInBackground(URL... urls) {
         int count = urls.length;
         long totalSize = 0;
         for (int i = 0; i < count; i++) {
             totalSize += Downloader.downloadFile(urls[i]);
             publishProgress((int) ((i / (float) count) * 100));
             // Escape early if cancel() is called
             if (isCancelled()) break;
         }
         return totalSize;
     }

     protected void onProgressUpdate(Integer... progress) {
         setProgressPercent(progress[0]);
     }

     protected void onPostExecute(Long result) {
         showDialog("Downloaded " + result + " bytes");
     }
 }

创建后,任务执行非常简单:

new DownloadFilesTask()。execute(url1,url2,url3);

AsyncTask的通用类型

异步任务使用的三种类型如下:

Params,执行时发送给任务的参数类型。 Progress,后台计算期间发布的进度单元的类型。 Result,后台计算结果的类型。 并非所有类型都始终由异步任务使用。要将类型标记为未使用,只需使用类型Void:

私有类MyTask扩展了AsyncTask {...}

4个步骤

执行异步任务时,任务将经历4个步骤:

onPreExecute(),在执行任务后立即在UI线程上调用。此步骤通常用于设置任务,例如通过在用户界面中显示进度条。

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

此步骤用于执行可能需要很长时间的后台计算。

异步任务的参数将传递给此步骤。

计算结果必须由此步骤返回,并将传递回最后一步。

此步骤还可以使用publishProgress发布一个或多个进度单元。这些值发布在UI线程的onProgressUpdate步骤中。

onProgressUpdate,在调用publishProgress后在UI线程上调用。执行的时间是不确定的。

此方法用于在后台计算仍在执行时显示用户界面中的任何形式的进度。

例如,它可用于为进度条设置动画或在文本字段中显示日志。

onPostExecute,在后台计算完成后在UI线程上调用。背景计算的结果作为参数传递给该步骤。

取消任务

可以通过调用cancel(boolean)随时取消任务。调用此方法将导致后续调用isCancelled()返回true。

调用此方法后,onCancelled(Object)将在onPostExecute(Object)返回后调用,而不是doInBackground(Object[])

为了确保尽快取消任务,您应该始终从isCancelled()定期检查doInBackground(Object[])的返回值,如果可能的话(例如在循环内)。

线程规则 此类必须遵循一些线程规则才能正常工作:

必须在UI线程上加载AsyncTask类。这是从android.os.Build.VERSION_CODES.JELLY_BEAN开始自动完成的。

必须在UI线程上创建任务实例。

必须在UI 线程上调用

执行

请勿手动调用 onPreExecute(), onPostExecute, doInBackground, onProgressUpdate

该任务只能执行一次(如果尝试第二次执行则会抛出异常。)

记忆可观察性

AsyncTask保证所有回调调用的同步方式使得以下操作在没有显式同步的情况下是安全的。

在构造函数或onPreExecute中设置成员字段,并在doInBackground中引用它们。

doInBackground中设置成员字段,并在onProgressUpdateonPostExecute中引用它们。

执行顺序

首次引入时,AsyncTasks在单个后台线程上串行执行。从android.os.Build.VERSION_CODES.DONUT开始,这被更改为一个线程池,允许多个任务并行运行。

android.os.Build.VERSION_CODES.HONEYCOMB开始,任务在单个线程上执行,以避免因并行执行而导致的常见应用程序错误。

如果您真的想要并行执行,可以使用executeOnExecutor(java.util.concurrent.Executor, Object[])

调用THREAD_POOL_EXECUTOR.

答案 2 :(得分:0)

Handler和AsyncTasks是在Android中使用UI / Event Thread实现多线程的方法。 Handler自Android API 1级和1级以来可用。 AsyncTask自API级别3开始可用。

什么是处理程序?

  1. Handler允许将消息添加到创建它的线程和它 还允许您安排某些runnable在某个时间执行 将来。
  2. Handler与应用程序的主线程相关联。它 处理和安排从后台发送的消息和runnables 线程到app主线程。
  3. 如果您正在执行多项重复任务,例如下载 要在ImageViews中显示的多个图像(如 下载时下载缩略图),使用任务队列 处理程序。
  4. 处理程序有两个主要用途。首先是安排消息 和runnables作为未来的某些点执行;第二个 是要在不同的线程上排队要执行的操作 你自己。使用这些方法完成调度消息 比如post(Runnable),postAtTime(Runnable,long), postDelayed(Runnable,long),sendEmptyMessage(int), sendMessage(Message),sendMessageAtTime(Message,long)和 sendMessageDelayed(Message,long)方法。
  5. 为您的应用程序创建进程时,其主要线程是 致力于运行一个负责管理的消息队列 顶级应用程序对象(活动,广播接收器等) 以及他们创造的任何窗户。
  6. 您可以创建自己的主题,并与主要主题进行通信 应用程序线程通过Handler。
  7. 什么是AsyncTask?

    1. 异步任务使您可以在不使用get的情况下实现多线程 双手肮脏的线程。 AsyncTask可以正常使用 允许执行后台操作和传递的方法 结果回到UI线程。

    2. 例如,如果您正在做与UI相关的隔离事项 下载数据以显示在列表中,继续使用AsyncTask。 理想情况下,AsyncTasks应该用于简短操作(少数几个 最多几秒钟。)

    3. 异步任务由3种泛型类型定义,称为Params, 进度和结果,以及4个步骤,称为onPreExecute, doInBackground,onProgressUpdate和onPostExecute。

    4. 在onPreExecute中,您可以定义需要执行的代码  在后台处理开始之前。

    5. doInBackground有需要在后台执行的代码,  在doInBackground中我们可以多次发送结果  事件线程通过publishProgress()方法,来通知后台  处理完成后我们可以简单地返回结果。

    6. onProgressUpdate()方法从中接收进度更新  doInBackground方法,通过publishProgress发布  方法,此方法可以使用此进度更新来更新  事件线程onPostExecute()方法处理返回的结果  doInBackground

    7. 使用的泛型类型是Params,即发送的参数类型  执行时的任务,进度,进度的类型  在背景计算期间发布的单位。

    8. 结果,后台计算结果的类型。

      1. 如果异步任务不使用任何类型,则可以将其标记为Void 类型。
      2. 可以通过调用cancel(boolean)来取消正在运行的异步任务 方法