9.2.4    使用 AsyncTask

不过为了更加方便我们在子线程中对 UI 进行操作,Android 还提供了另外一些好用的工 具,AsyncTask 就是其中之一。借助 AsyncTask,即使你对异步消息处理机制完全不了解, 也可以十分简单地从子线程切换到主线程。当然,AsyncTask 背后的实现原理也是基于异步 消息处理机制的,只是 Android 帮我们做了很好的封装而已。

首先来看一下 AsyncTask 的基本用法,由于 AsyncTask 是一个抽象类,所以如果我们想 使用它,就必须要创建一个子类去继承它。在继承时我们可以为 AsyncTask 类指定三个泛型 参数,这三个参数的用途如下。

1.    Params

在执行 AsyncTask 时需要传入的参数,可用于在后台任务中使用。

2.    Progress

后台任务执行时,如果需要在界面上显示当前的进度,则使用这里指定的泛型作为 进度单位。

3.    Result

当任务执行完毕后,如果需要对结果进行返回,则使用这里指定的泛型作为返回值 类型。

因此,一个最简单的自定义 AsyncTask 就可以写成如下方式:

class DownloadTask extends AsyncTask<Void, Integer, Boolean> {

……

}

这里我们把 AsyncTask 的第一个泛型参数指定为 Void,表示在执行 AsyncTask 的时候不 需要传入参数给后台任务。第二个泛型参数指定为 Integer,表示使用整型数据来作为进度显 示单位。第三个泛型参数指定为 Boolean,则表示使用布尔型数据来反馈执行结果。

当然,目前我们自定义的 DownloadTask 还是一个空任务,并不能进行任何实际的操作, 我们还需要去重写 AsyncTask 中的几个方法才能完成对任务的定制。经常需要去重写的方法 有以下四个。

1.    onPreExecute()

这个方法会在后台任务开始执行之前调用,用于进行一些界面上的初始化操作,比 如显示一个进度条对话框等。

2.    doInBackground(Params...)

这个方法中的所有代码都会在子线程中运行,我们应该在这里去处理所有的耗时任 务。任务一旦完成就可以通过 return 语句来将任务的执行结果返回,如果 AsyncTask 的 第三个泛型参数指定的是 Void,就可以不返回任务执行结果。注意,在这个方法中是不 可以进行 UI 操作的,如果需要更新 UI 元素,比如说反馈当前任务的执行进度,可以调 用 publishProgress(Progress...)方法来完成。

3.    onProgressUpdate(Progress...)

当在后台任务中调用了 publishProgress(Progress...)方法后,这个方法就会很快被调 用,方法中携带的参数就是在后台任务中传递过来的。在这个方法中可以对 UI 进行操 作,利用参数中的数值就可以对界面元素进行相应地更新。

4.    onPostExecute(Result)

当后台任务执行完毕并通过 return 语句进行返回时,这个方法就很快会被调用。返 回的数据会作为参数传递到此方法中,可以利用返回的数据来进行一些 UI 操作,比如 说提醒任务执行的结果,以及关闭掉进度条对话框等。

因此,一个比较完整的自定义 AsyncTask 就可以写成如下方式:

class DownloadTask extends AsyncTask<Void, Integer, Boolean> {

@Override

protected void onPreExecute() {

progressDialog.show(); // 显示进度对话框

}

@Override

protected Boolean doInBackground(Void... params) {

try {

while (true) {

int downloadPercent = doDownload(); // 这是一个虚构的方法

publishProgress(downloadPercent);

if (downloadPercent >= 100) {

break;

}

}

} catch (Exception e) {

return false;

}

return true;

}

@Override

protected void onProgressUpdate(Integer... values) {

// 在这里更新下载进度

progressDialog.setMessage("Downloaded " + values[0] + "%");

}

@Override

protected void onPostExecute(Boolean result) {

progressDialog.dismiss(); // 关闭进度对话框

// 在这里提示下载结果

if (result) {

Toast.makeText(context, "Download succeeded", Toast.LENGTH_SHORT).show();

} else {

Toast.makeText(context, " Download failed", Toast.LENGTH_SHORT).show();

}

}

}

在这个 DownloadTask 中,我们在 doInBackground()方法里去执行具体的下载任务。这个方法里的代码都是在子线程中运行的,因而不会影响到主线程的运行。注意这里虚构了一个 doDownload()方法,这个方法用于计算当前的下载进度并返回,我们假设这个方法已经存在
了 。 在 得 到 了 当 前 的 下 载 进 度 后 , 下 面 就 该 考 虑 如 何 把 它 显 示 到 界 面 上 了 , 由 于 doInBackground()方法是在子线程中运行的,在这里肯定不能进行 UI 操作,所以我们可以调
用 publishProgress()方法并将当前的下载进度传进来,这样 onProgressUpdate()方法就会很快 被调用,在这里就可以进行 UI 操作了。

当下载完成后,doInBackground()方法会返回一个布尔型变量,这样 onPostExecute()方 法就会很快被调用,这个方法也是在主线程中运行的。然后在这里我们会根据下载的结果来
弹出相应的 Toast 提示,从而完成整个 DownloadTask 任务。

简单来说,使用 AsyncTask 的诀窍就是,在 doInBackground()方法中去执行具体的耗时 任务,在 onProgressUpdate()方法中进行 UI 操作,在 onPostExecute()方法中执行一些任务的 收尾工作。

如果想要启动这个任务,只需编写以下代码即可:

new DownloadTask().execute();

以上就是 AsyncTask 的基本用法,怎么样,是不是感觉简单方便了许多?我们并不需要
去考虑什么异步消息处理机制,也不需要专门使用一个 Handler 来发送和接收消息,只需要
调用一下
publishProgress()方法就可以轻松地从子线程切换到 UI 线程了。

android: 使用 AsyncTask的更多相关文章

  1. Android笔记——AsyncTask介绍

    AsyncTask和Handler对比 1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操 ...

  2. Android—初识AsyncTask

    AsyncTask是用来处理一些后台的比较耗时的任务,给用户带来良好的体验.AsyncTask扩展Thread,增强了与主线程的交互能力. 首先介绍AsyncTask中定义的以下几个方法: onPre ...

  3. 详解Android中AsyncTask的使用

    在Android中实现异步任务机制有两种方式,Handler和AsyncTask. Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更 ...

  4. 55.Android之AsyncTask介绍 (转)

    AsyncTask和Handler对比 1 ) AsyncTask实现的原理,和适用的优缺点 AsyncTask,是android提供的轻量级的异步类,可以直接继承AsyncTask,在类中实现异步操 ...

  5. android高级---->AsyncTask的源码分析

    在Android中实现异步任务机制有两种方式,Handler和AsyncTask,它在子线程更新UI的例子可以参见我的博客(android基础---->子线程更新UI).今天我们通过一个小的案例 ...

  6. Android 多线程----AsyncTask异步任务详解

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/3 ...

  7. Android使用AsyncTask实现可以断点续传的DownloadManager功能

    http://www.it165.net/pro/html/201211/4210.html 最近做项目卡壳了,要做个Android的应用市场,其他方面都还好说,唯独这个下载管理算是给我难住了,究其原 ...

  8. Android测试AsyncTask下载图片

    package com.example.myact8_async; import org.apache.http.HttpEntity; import org.apache.http.HttpResp ...

  9. Android开发——AsyncTask详解

    android提供AsynvTask,目的是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的. Android为了降低开发难度,提供了AsyncTask.Asyn ...

  10. 具体解释Android中AsyncTask的使用

    在Android中实现异步任务机制有两种方式,Handler和AsyncTask. Handler模式须要为每个任务创建一个新的线程,任务完毕后通过Handler实例向UI线程发送消息,完毕界面的更新 ...

随机推荐

  1. ubuntu14.04 的网络配置

    为eth0 配置网络 vi /etc/network/intefaces 添加以下内容 auto eth0 iface eth0 inet static address 192.168.0.10 ne ...

  2. jzoj[1438]NOIP2013火柴排队

    读题: 相邻两个火柴可以交换?两个火柴序列?嗅到了归并排序的味道. 读完题目之后,我们可以知道,如果想要交换次数最少,可以先固定一个序列不变,比如说a序列不变,变b序列 样例是 4 2 3 1 4 3 ...

  3. 【转】进程与CPU

    声明:本博客转自:http://blog.chinaunix.net/uid-20737871-id-1881246.html 简单地说,CPU 亲和性(affinity) 就是进程要在某个给定的 C ...

  4. Java泛型总结(转)

    本文是转载,原文链接:http://www.cnblogs.com/lwbqqyumidi/p/3837629.html 一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: ...

  5. db2 怎么计算两个时间相差多少个月。如2015-10-10 和2014-1-12

    SELECT timestampdiff (256, char(timestamp('2013-12-30 20:30:30') - timestamp('2001-09-26 15:24:23')) ...

  6. 再详细的介绍一下Unity5的AssetBundle

    之前曾经写了一篇博客介绍Unity5的AssetBundle,结果似乎很受关注.不过似乎很多人看了之后都不懂,主要是因为不太明白AssetBundle是什么,它的依赖关系和结构是什么的,就直接想拿代码 ...

  7. Android 6.0 新功能及主要 API 变更

    运行时权限 这个版本中引入了新的权限模型,现在用户可以在运行时直接管理应用程序的权限.这个模型基于用户对权限控制的更多可见性,同时为应用程序的开发者提供更流畅的应用安装和自动升级.用户可以为已安装的每 ...

  8. Entity Framework Code First 学习

    1.添加entityframework 项目-管理解决方案的 NuGet 程序包-联机-Entity Framework 2.code first Migration 工具->库程序包管理器-& ...

  9. Myeclipse加载maven

    1.自带,需要将之前下好的文本加入到myeclipse中即可.windows---->preference---->Myeclipse---->MavenMyeclipse 3.将本 ...

  10. Linq to sql 语法方法示例

    联表查询,判断追加条件,对集合分页 ) { var data = from m in _db.AppArticleComment join o in _db.AppArticle on m.Artic ...