AsyncTask==Handler+Thread对比使用说明

2016-03-08 20:06 阅读 4,522 次 评论 0 条
版权声明:本文著作权归TeachCourse所有,未经许可禁止转载,谢谢支持!
转载请注明出处:http://teachcourse.cn/1535.html

摘要

AsyncTask能够合理且轻松使用UI线程,该类允许执行后台操作和发送结果到UI线程而不需要操作threads或handlers。

AsyncTask是针对Thread和Handler代替而封装好的一个工具,但不构成一个通用的线程框架。AsyncTask最理想地被用于短暂的操作,如果你需要长时间保持线程运行,建议最好使用java.util.concurrent包提供的Executor、ThreadPoolExecutor、FutureTask等类。

一个异步任务被评估后定义并在后台线程运行,将结果发送回UI线程。一个异步任务由三个泛型和四个步骤组成,三个泛型分别是:Params、Progress和Result,四个方法分别是:onPreExecute、doInBackground、onProgressUpdate和onPostExecute

简单Demo介绍

AsyncTask必须作为一个子类使用,该子类将至少重写一个方法(doInBackground(Params...)),通常还重写另一个方法(onPostExecute(Result)

下面是一个简单的例子:

  1. private class DonwloadFilesTask extends AsyncTask<URL, Integer, Long> {  
  2.         @Override  
  3.         protected void onPreExecute() {  
  4.             // TODO Auto-generated method stub  
  5.             super.onPreExecute();  
  6.             // 显示下载进度条  
  7.             mProgressDialog.show();  
  8.         }  
  9.   
  10.         @Override  
  11.         protected Long doInBackground(URL... params) {  
  12.             int count = params.length;  
  13.             long totalsize = 0;  
  14.             for (int i = 0; i < count; i++) {  
  15.                 totalsize += Downloader.loadFile(params[i]);  
  16.                 publishProgress((int) ((i / (float) count) * 100));//更新进度条  
  17.                 if (isCancelled())  
  18.                     break;  
  19.             }  
  20.             return totalsize;//返回下载数据大小,在onPostExecute()方法中处理  
  21.         }  
  22.   
  23.         @Override  
  24.         protected void onProgressUpdate(Integer... values) {  
  25.             // TODO Auto-generated method stub  
  26.             super.onProgressUpdate(values);  
  27.             setProgressPercent(values[0]);  
  28.         }  
  29.   
  30.         @Override  
  31.         protected void onPostExecute(Long result) {  
  32.             // TODO Auto-generated method stub  
  33.             super.onPostExecute(result);  
  34.             showDialog("Downloaded " + result + " bytes");  
  35.             mProgressDialog.dismiss();  
  36.         }  
  37.   
  38.     }  

在UI线程中创建Task,然后执行。

  1. new DonwloadFilesTask().execute(mUrl1,mUrl2,mUrl3);  

AsyncTask通用的类型

1、Params,被发送到task中执行的元素类型

2、Progress,后台计算传送进度类型

3、Result,后台计算结果类型

在一个异步任务中并不是所有的类型都是必须的,为了标记一个类型是无用的,通常使用Void:

private class MyTask extends AsyncTask{...}

四个步骤

当一个异步任务被执行,该异步任务需要经历四个步骤:

1、onPreExecute(),异步任务执行之前在UI thread中调用,通常被用来创建当前任务,实例化进度条对象

2、doInBackground(Params...),在执行完onPreExecute()后立即被调用的方法,通常被用来执行后台可能需要花费很长时间的计算。异步任务传入的元素在这里被调用,计算的结果必须通过当前步骤返回并传送到最后的onPostExecute()方法中。在这个步骤中,可能需要使用publishProgress(Progress...)方法来公布一个或多个进度单元值,这些进度单元值被公布在UI线程中,在onProgressUpdate(Progress...)中调用

3、onProgressUpdate(Progress...),该方法在publishProgress(Progress...)被回调后调用,执行的时间长短未被定义,但该方法显示任务还在后台执行的进度信息,比如:你可以被用来展示进度条动画或打印出logs信息

4、onPostExecute(Result),在异步任务结束后在UI thread中调用的方法,后台计算的结果被作为一个参数传递到该步骤

取消异步任务

调用cancle(boolean)方法取消还在执行的异步任务,调用该方法后将会回调isCancelled()方法返回true。在调用该方法后,onCancelled(Object)代替了onPostExecute(Object)在执行完doInBackground(Object[])后回调。为了保证当前任务尽快被取消,你应该经常检查isCancelled()返回值情况

线程规则

为保证AsyncTask类能够正确执行,下面是几个需要遵循的线程规则:

1、AsyncTask类必须在UI线程中被加载

2、AsyncTask类实例必须在UI线程中实例化

3、execute(Params...)方法必须在UI线程中调用

4、不允许手动回调 onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)方法

5、当前任务只能被执行一次(否则抛出异常)

Memory observability

通过下面操作步骤,AsyncTask保证所有回调都是异步、安全的:

1、在构造方法或onPreExecute()中设置成员变量,在doInBackground()方法中引用

2、在doInBackground()中设置成员变量,在onProgressUpdate(Progress...)和onPostExecute()方法中引用

AsyncTask执行的顺序

正如前面介绍的,AsyncTask是被序列化执行在单一的后台线程中,从DONUT版本开始,改变一个线程池允许多个任务并行操作。从HONEYCOMB版本开始,在一个单一的线程上执行任务,以避免并行执行导致常见的应用错误。

如果你确实想并发执行,你可以调用executeOnExecutor(java.util.concurrent.Executor, Object[]) 通过THREAD_POOL_EXECUTOR

推荐阅读:

Android开发之ProgressDialog读取文件进度解析

Android之ProgressBar读取文件进度解析

ProgressBar+WebView实现自定义浏览器

WebView控件实现的简单浏览器效果

关注公众号 扫一扫二维码,加我QQ

如果文章对你有帮助,欢迎点击上方按钮关注作者

来源:TeachCourse每周一次,深入学习Android教程,关注(QQ1589359239或公众号TeachCourse)
转载请注明出处:http://teachcourse.cn/1535.html

资源分享

源码下载
分类:Android, 开发基础 标签:,
Android学习笔记六:Java基础知识 Android学习笔记六:Java基础知
Map接口集合方法解析 Map接口集合方法解析
Easy WP SMTP 插件,wordpress万网主机smtp发邮件失败解决办法 Easy WP SMTP 插件,word
深入理解接口的定义和意义(2)之MVP实例 深入理解接口的定义和意义(2)之

发表评论

呲牙 憨笑 坏笑 偷笑 色 微笑 抓狂 睡觉 酷 流汗 鼓掌 大哭 可怜 疑问 晕 惊讶 得意 尴尬 发怒 奋斗 衰 骷髅 啤酒 吃饭 礼物 强 弱 握手 OK NO 勾引 拳头 差劲 爱你

表情