和使用匿名线程想比较来说 AsyncTask 有如下好处:

  1.线程的开销较大,如果每个任务都要创建一个线程,那么应用程 序的效率要低很多;

  2.线程无法管理,匿名线程创建并启动后就不受程序的控制了,如果有很多个请求发送,那么就会启动非常多的线程,系统将不堪重负。

  3.另外,在新线程中更新UI还必须要引入handler,这让代码看上去非常臃肿。

  为了解决这一问题,Android在1.5版本引入了AsyncTask。AsyncTask的特点是任务在主线程之外运行,而回调方法是在主线程中执行,这就有效地避免了使用Handler带来的麻烦。阅读AsyncTask的源码可知,AsyncTask是使用java.util.concurrent 框架来管理线程以及任务的执行的,concurrent框架是一个非常成熟,高效的框架,经过了严格的测试。这说明AsyncTask的设计很好的解决了匿名线程存在的问题。

AsyncTask定义了三种泛型类型 Params,Progress和Result。

Params 启动任务执行的输入参数,比如HTTP请求的URL。

Progress 后台任务执行的百分比。

Result 后台执行任务最终返回的结果,比如String。

子类必须实现抽象方法doInBackground(Params… p) ,在此方法中实现任务的执行工作,比如连接网络获取数据等。通常还应该实现onPostExecute(Result r)方法,因为应用程序关心的结果在此方法中返回。需要注意的是AsyncTask一定要在主线程中创建实例。

AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,需要注意的是这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。在任务的执行过程中,这些方法被自动调用,运行过程,

onPreExecute() 当任务执行之前开始调用此方法,可以在这里显示进度对话框。

doInBackground(Params…) 此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。

onProgressUpdate(Progress…) 此方法在主线程执行,用于显示任务执行的进度。

onPostExecute(Result) 此方法在主线程执行,任务执行的结果作为此方法的参数返回。

class GetImageTask extends AsyncTask<String, Void, Bitmap>{ InputStream is = null; @Override protected Bitmap doInBackground(String... params) { // TODO Auto-generated method stub URL myFileUrl = null; Bitmap bitmap = null; InputStream is = null; HttpURLConnection conn = null; try { myFileUrl = new URL(params[0]); } catch (MalformedURLException e) { e.printStackTrace(); } try { conn = (HttpURLConnection) myFileUrl .openConnection(); conn.setDoInput(true); conn.connect(); is = conn.getInputStream(); bitmap = BitmapFactory.decodeStream(is); is.close(); } catch (IOException e) { e.printStackTrace(); }finally{ try { if(is != null){ is.close(); } if( conn != null){ conn.disconnect(); } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return bitmap; } @Override protected void onCancelled() { // TODO Auto-generated method stub super.onCancelled(); } @Override protected void onPostExecute(Bitmap result) { // TODO Auto-generated method stub mImageAndTextView.setImage(result); mImageAndTextView.postInvalidate(0, 0 , mScreenWidth ,mImageHeight + 30); //只更新稍比图片大一些的区域 super.onPostExecute(result); } }

更多相关文章

  1. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析
  2. Android(安卓)如何获取应用签名,微信需要的签名是MD5还是SHA1?
  3. 当你说不行时,你应该说些什么:以Android播放midi为例
  4. 作为Android开发者 你真的知道app从启动到主页显示的过程吗?
  5. Android调用H5的方法.Js交互
  6. Flutter调用Android和iOS原生代码的方法示例
  7. Android(安卓)View获取坐标值、相对距离的方法
  8. 破解某国外收费的RTMP Client并成功在Android和Java上调用
  9. Android(三)数据存储之XML解析技术

随机推荐

  1. 一次Mysql使用IN大数据量的优化记录
  2. 详解mysql慢日志查询
  3. mysql8.0.20配合binlog2sql的配置和简单
  4. MySQL索引失效的几种情况汇总
  5. 详解MySQL 聚簇索引与非聚簇索引
  6. MySQL 索引的优缺点以及创建索引的准则
  7. MySQL MyISAM 与InnoDB 的区别
  8. MySQL btree索引与hash索引区别
  9. mysql group by 对多个字段进行分组操作
  10. 基于JPQL实现纯SQL语句方法详解