转自:Android AsyncTask完全解析,带你从源码的角度彻底理解

另外一篇比较详细的博文:http://blog.csdn.net/liuhe688/article/details/6532519

http://stackoverflow.com/questions/9671546/asynctask-android-example

AsyncTask的基本用法

首先来看一下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("当前下载进度:" + values[0] + "%");
} @Override
protected void onPostExecute(Boolean result) {
progressDialog.dismiss();
if (result) {
Toast.makeText(context, "下载成功", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(context, "下载失败", Toast.LENGTH_SHORT).show();
}
}
}

这里我们模拟了一个下载任务,在doInBackground()方法中去执行具体的下载逻辑,在onProgressUpdate()方法中显示当前的下载进度,在onPostExecute()方法中来提示任务的执行结果。如果想要启动这个任务,只需要简单地调用以下代码即可:

 new DownloadTask().execute();

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

以上只是实现了AsyncTask的用法,具体的实现机制,需要参考大神郭霖的博客了。http://blog.csdn.net/guolin_blog/article/details/11711405

Android开发之异步消息处理机制AsyncTask的更多相关文章

  1. Android开发之异步消息处理机制Handler

    更加详细的介绍Handler的博文-http://blog.csdn.net/guolin_blog/article/details/9991569 Android中的异步消息处理主要有四个部分组成, ...

  2. Android线程之异步消息处理机制(三)——AsyncTask

    Android的异步消息处理机制能够很完美的解决了在子线程中进行UI操作的问题,但是为了更加方便我们在子线程中对UI进行操作,Android还提供了另一个很好用的工具,AsyncTask就是其中之一. ...

  3. Android线程与异步消息处理机制

    在程序开发时,对于一些比较耗时的操作,我们通常会为其开辟一个单独的线程来执行,这样可以尽可能的减少用户等待的时间.在Android中,默认情况下,所有的操作都是在主线程中进行的,这个主线程负责管理与U ...

  4. Android学习之异步消息处理机制

    •前言 我们在开发 APP 的过程中,经常需要更新 UI: 但是 Android 的 UI 线程是不安全的: 如果想更新 UI 线程,必须在进程的主线程中: 这里我们引用了异步消息处理机制来解决之一问 ...

  5. Android线程之异步消息处理机制(二)——Message、Handler、MessageQueue和Looper

    异步消息处理机制解析 Android中的异步消息处理主要有四个部分组成,Message.Handler.MessageQueue和Looper. 1.Message Message是在线程之间传递的消 ...

  6. Android线程之异步消息处理机制(一)

    Android不允许在子线程中进行UI操作,但是有些时候,我们必须在子线程里去执行一些耗时任务,然后根据任务的执行结果来更新相应的UI控件.对于这种情况,Android提供了一套异步消息处理机制,完美 ...

  7. Android之Handler(异步消息处理)机制

    1. 概述 Handler . Looper .Message 这三者都与Android异步消息处理线程相关的概念.那么什么叫异步消息处理线程呢?异步消息处理线程启动后会进入一个无限的循环体之中,每循 ...

  8. Android Learning:多线程与异步消息处理机制

    在最近学习Android项目源码的过程中,遇到了很多多线程以及异步消息处理的机制.由于之前对这块的知识只是浅尝辄止,并没有系统的理解.但是工程中反复出现让我意识到这个知识的重要性.所以我整理出这篇博客 ...

  9. Android中Handler的消息处理机制以及源码分析

    在实际项目当中,一个很常见的需求场景就是在根据子线程当中的数据去更新ui.我们知道,android中ui是单线程模型的,就是只能在UI线程(也称为主线程)中更新ui.而一些耗时操作,比如数据库,网络请 ...

随机推荐

  1. ###C中的extern-static-const关键词

    #@date: 2014-06-14 #@author: gerui #@email: forgerui@gmail.com Contents extern的作用一般是用来声音一个外部变量和函数.一般 ...

  2. JavaScript中,按值传递与按地址(引用)传递。

    JavaScript中,数字型,字符串,布尔型等基本类型,传递给变量时,传递方式为按值传递,这个很好理解,不做多解释. 而令人有所疑惑的,是数组,对象等引用类型传递给变量是,传递方式为按地址传递.此处 ...

  3. 19_高级映射:一对多查询(使用resultMap)

    [需求] 查询订单以及订单明细的信息. 确定主查询表:订单表orders 确定关联查询表:订单明细表 orderdetail 在一对一查询的基础上添加订单明细表关联即可. [分析] 使用resultM ...

  4. 【转载】C#后台声明式验证,远离if验证

    ViewModel public class ViewModel { [Required(ErrorMessage="标题不能为空")] public string Title { ...

  5. jQuery 1.7以后 jQuery2 新元素绑定事件on替代live

    最近做了一个类别动态加载的功能,jQuery版本用的是2.02. 绑定事件jQuery1.7之前用的是live或者是bind.新版的jQuery新增了on方法 由于子类别是动态加载的,默认是不会有事件 ...

  6. [C#]将千分位字符串转换成数字

    关键代码: /// <summary> /// 将千分位字符串转换成数字 /// 说明:将诸如"–111,222,333的千分位"转换成-111222333数字 /// ...

  7. MySQL中SQL语句的分类

    1:数据定义语言(DDL) :创建和删除数据库(CREATE DATABASE || DROP  DATABASE):2:创建.修改.重命名.删除表(CREATE  TABLE || ALTER TA ...

  8. VC++对话框中添加状态栏的方法

    方法一:1.添加成员变量CStatusBarCtrl m_StatusBar;2.在OnInitDialog()中加入:                  m_StatusBar.Create(WS_ ...

  9. DB2实用命令记录

    quiesce tablespace quiesce tablespaces for table <table_name> share; Monitor Switches details ...

  10. 【python】Python 3 +pycharm中文支持解决方案

    使用环境:window10 + python 3.5.1 方法:在代码前端增加代码:# -*-coding:gbk-*-