在Android中实现异步任务机制有两种方式,Handler和AsyncTask。Handler模式需要为每一个任务创建一个新的线程,任务完成后通过Handler实例向UI线程发送消息,完成界面的更新,这种方式对于整个过程的控制比较精细,但也是有缺点的,例如代码相对臃肿,在多个任务同时执行时,不易对线程进行精确的控制,AsyncTask,它使创建异步任务变得更加简单,不再需要编写任务线程和Handler实例即可完成相同的任务。

AsyncTask是定义异步任务在后台线程(子线程中)运行的,而结果更新UI在UI线程中,接收三个参数,Params(传入的值)Progress(进度) Result(返回的结果),有四步onPreExecute(在UI线程中执行,准备操作)doInBackground(子线程中耗时操作)onProgressUpdate (进度更新)onPostExecute(结果返回)

来看下executeOnExecutor()方法:

 @MainThread(主线程中调用的)public final AsyncTask<Params, Progress, Result> executeOnExecutor(Executor exec,Params... params) {//这里有一些异常的判断 ,由于代码量多,我就去掉了,在这里我们不考虑异常问题//在这里首先吧状态给位RUNNINGmStatus = Status.RUNNING;//执行前的准备工作onPreExecute();//这里的params就是我们传入的值,然后赋值给了mWorker,那么我们就要看看这个是什么意思了mWorker.mParams = params;//用线程池执行这个futureexec.execute(mFuture);//最终返回自己return this;}

首先AsyncTask是一个抽象类,必须要创建它的子类。但是在继承AsyncTask类的时候,需要指定三个泛型参数。解释分别如下:

(1)Params

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

(2)Progress

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

(3)Result

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

然后一般在子类中,需要重写下面的几个回调方法,他们都是自动被调用的,不要在代码中人工调用。

(1)onPreExexute()

该方法在后台任务执行前,即doInBackground方法执行前被调用。通常在这里执行一些初始化的操作,比如显示一个进度条。

(2)doInBackground(Params...)

该方法用来执行后台任务,它的所有代码都是在子线程中操作,任务一旦完成就会用return来返回结果。当然它的参数和返回结果的类型就是上面我们所指定的Params和Result。千万注意,不要在这个

方法中执行更新UI的操作。如果需要更新UI元素,比如说反馈当前任务的进度,可以调用publishProgress(Progress...)方法来完成。

(3)onProgressUpdate(Progress...)

当在后台任务中调用了publishProgress方法后,就会自动调用该方法,方法中的参数就是publishProgress方法传递过来的。这个方法可以对UI进行更新。

(4)onPostExecute(Result)

当后台任务执行完毕,即doInBackground执行完毕后,该方法被调用。doInBackground返回的结果就是该方法的参数,这这里可以执行任务完成后的逻辑,比如说关闭一个进度条,更新一些UI等。

需要说明的是这几个方法,只有doInBackground方法是在子线程中执行的,其他的都是在主线程中执行的。那么启动和取消这个任务的方法是什么呢?如下:

myAsyncTask.execute()其中该任务

yAsyncTask.cancel()取消该任务

Android AsyncTask注意事项

1. AsyncTask对象不可重复使用,也就是说一个AsyncTask对象只能execute()一次,否则会有异常抛出"java.lang.IllegalStateException: Cannot execute task: the task is already running"

2. 在doInBackground()中要检查isCancelled()的返回值,如果你的异步任务是可以取消的话。cancel()仅仅是给AsyncTask对象设置了一个标识位,当调用了cancel()后,发生的事情只有:AsyncTask对象的标识位变了,和doInBackground()执行完成后,onPostExecute()不会被回调了,而doInBackground()和 onProgressUpdate()还是会继续执行直到doInBackground()结束。所以要在doInBackground()中不断的检查 isCancellled()的返回值,当其返回true时就停止执行,特别是有循环的时候。如上面的例子,如果把读取数据的isCancelled() 检查去掉,图片还是会下载,进度也一直会走,只是最后图片不会放到UI上(因为onPostExecute()没被回调)!这里的原因其实很好理解,想想Java SE的Thread吧,是没有方法将其直接Cacncel掉的,那些线程取消也无非就是给线程设置标识位,然后在run()方法中不断的检查标识而已。

3. 如果要在应用程序中使用网络,一定不要忘记在AndroidManifest中声明INTERNET权限,否则会报出很诡异的异常信息,比如上面的例子,如果把INTERNET权限拿掉会抛出"UnknownHostException"。刚开始很疑惑,因为模拟器是可以正常上网的,后来Google了下才发现原来是没权限,但是疑问还是没有消除,既然没有声明网络权限,为什么不直接提示无网络权限呢?对比Java SE的Thread Thread是非常原始的类,它只有一个run()方法,一旦开始,无法停止,它仅适合于一个非常独立的异步任务,也即不需要与主线程交互,对于其他情况,比如需要取消或与主线程交互,都需添加额外的代码来实现,并且还要注意同步的问题。而AsyncTask是封装好了的,可以直接拿来用,如果你仅执行独立的异步任务,可以仅实现doInBackground()。

所以,当有一个非常独立的任务时,可以考虑使用Thread,其他时候,尽可能的用 AsyncTask。

AsyncTask是什么相关推荐

  1. android asynctask源码分析,Android通过Handler与AsyncTask两种方式动态更新ListView(附源码)...

    本文实例讲述了Android通过Handler与AsyncTask两种方式动态更新ListView的方法.分享给大家供大家参考,具体如下: 有时候我们需要修改已经生成的列表,添加或者修改数据,noti ...

  2. 【Android】AsyncTask异步类

    一.关于AysncTask AsyncTask使得多线程编程更加简单,AsyncTask能在后台线程执行异步任务,并且在UI线程更新界面,而不再需要用户去操作Thread和Handler.AysncT ...

  3. Asynctask源码分析

    ​ 首先我们使用AsyncTask时,一般是: new AsyncTask(...).execute() 复制代码 我们看new AsyncTask(),它走的是: public AsyncTask( ...

  4. Android 多线程-----AsyncTask详解

    您可以通过点击 右下角 的按钮 来对文章内容作出评价, 也可以通过左下方的 关注按钮 来关注我的博客的最新动态. 如果文章内容对您有帮助, 不要忘记点击右下角的 推荐按钮 来支持一下哦 如果您对文章内 ...

  5. android一个简单的异步AsyncTask下载数示例,简单下载(07)

    2019独角兽企业重金招聘Python工程师标准>>> public class MainActivity extends Activity {private ImageView i ...

  6. Android 消息异步处理之AsyncTask

    Android提供了异步处理消息的方式大致有两种,第一种是handler+Thread,之前已经对于这种方式做过分析,第二种就是AsyncTask,这是Android1.5提供的一种轻量级的工具类,其 ...

  7. Android 学习笔记--android——AsyncTask在Android4.X的机制问题

    AsyncTask在Android4.X的机制问题 AsyncTask在Android4.X机制是串行的...单一AsyncTask运行完才会运行下一个 AsyncTask在Android2.3机制是 ...

  8. AsyncTask进度条加载网站数据到ListView

    2019独角兽企业重金招聘Python工程师标准>>> 代码介绍: 初学android,写了个一小demo.功能很简单,主要是用来学习, 知识要点: 1.android全局变量的使用 ...

  9. 源码篇——AsyncTask机制

    AsyncTask new AsyncTask<String,String,String>(){// 运行在主线程中,做预备工作onPreExecute(){}// 运行在子线程中,做耗时 ...

  10. Android中 AsyncTask

    Android AsyncTask 在程序处理中必然会遇上耗时的操作,如访问网络,下载数据,访问数据库等,如何存在耗时的操作 又不能影响界面显示交互. 在某些耗时可以控制的情况下,我们可以分批操作,对 ...

最新文章

  1. 输入和输出移位寄存器的同步串行模式
  2. list替换某一项需要遍历比对再set到对应的position
  3. 【Java并发编程】java并发框架Executor学习笔记
  4. Spring Boot JPA中使用@Entity和@Table
  5. Dapper逆天入门~强类型,动态类型,多映射,多返回值,增删改查+存储过程+事物案例演示...
  6. git-分支的冲突与冲突的解决
  7. a recordset php,UsingCOMwithPHP(我就不翻译了)_PHP
  8. hdu 1231 最大连续子序列 ,1003 Max Sum;
  9. 一种可提高导师寿命的有效方案
  10. ThreadPoolExecutor运转机制详解
  11. 深入理解JVM-字节码
  12. 海康威视错误代码说明(六)(错误代码:82~825)
  13. linux4755代表什么权限,CentOS下chmod 755和4755的区别是什么?
  14. java pdf 加图片_java实现在pdf模板的指定位置插入图片
  15. python对大小写敏感吗_python中对于大小写是否敏感
  16. 『 文件操作 』文件批量改名
  17. MOS 转载 ORA-1555 诊断和分析
  18. UVM验证方法学之一验证平台
  19. solid works定义样条曲线
  20. win10无法装载iso文件_Win10系统怎么安装iso镜像文件 Win10系统安装iso镜像文件方法...

热门文章

  1. 淘宝客如何通过闲鱼引流?淘宝客、闲鱼营销推广方式有哪些?
  2. 闲鱼怎么引流到淘宝客?吸引住大量的粉丝
  3. 手机网络邻居访问电脑_通过WiFi局域网在手机上观看电脑上的视频
  4. python人机对战_【人机对战】用python打造经典井字游戏
  5. 概率图模型(PGM)综述-by MIT 林达华博士
  6. 汇纳科技张宏俊:加强布局AI大数据,为实体商业服务
  7. 人工智能未来替代的职位,主要有哪些行业?
  8. 为什么总显示连接服务器失败怎么回事,为什么总是出现"与总服务器连接失败"的字样 – 手机爱问...
  9. 基本极限定理(切比雪夫不等式,大数定律,中心极限定理)
  10. GA-LSTM的国内外研究现状