注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

是缘是情是童真

如果你用笑脸面对 你会看见别人的笑脸

 
 
 

日志

 
 

Android AsyncTask 的使用  

2011-07-19 16:03:37|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

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

  • 线程的开销较大,如果每个任务都要创建一个线程,那么应用程 序的效率要低很多;
  • 线程无法管理,匿名线程创建并启动后就不受程序的控制了,如果有很多个请求发送,那么就会启动非常多的线程,系统将不堪重负。
  • 另外,前面已经看到,在新线程中更新UI还必须要引入handler,这让代码看上去非常臃肿
  • 为了解决这一问题,Android在1.5版本引入了AsyncTask。AsyncTask的特点是任务在主线程之外运行,而回调方法是在主线程中执行,这就有效地避免了使用Handler带来的麻烦。阅读AsyncTask的源码可知,AsyncTask是使用java.util.concurrent 框架来管理线程以及任务的执行的,concurrent框架是一个非常成熟,高效的框架,经过了严格的测试。这说明AsyncTask的设计很好的解决了匿名线程存在的问题。
    AsyncTask是抽象类,其结构图如下图所示:

    Android  AsyncTask 的使用 - 子衡 - 子衡的博客
    AsyncTask定义了三种泛型类型 Params,Progress和Result。
    • Params 启动任务执行的输入参数,比如HTTP请求的URL。
    • Progress 后台任务执行的百分比。
    • Result 后台执行任务最终返回的结果,比如String。

    子类必须实现抽象方法doInBackground(Params… p) ,在此方法中实现任务的执行工作,比如连接网络获取数据等。通常还应该实现onPostExecute(Result r)方法,因为应用程序关心的结果在此方法中返回。需要注意的是AsyncTask一定要在主线程中创建实例。
    AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,需要注意的是这些方法不应该由应用程序调用,开发者需要做的就是实现这些方法。在任务的执行过程中,这些方法被自动调用,运行过程,如下图所示:

    Android  AsyncTask 的使用 - 子衡 - 子衡的博客

     

    • onPreExecute() 当任务执行之前开始调用此方法,可以在这里显示进度对话框。
    • doInBackground(Params…) 此方法在后台线程执行,完成任务的主要工作,通常需要较长的时间。在执行过程中可以调用publicProgress(Progress…)来更新任务的进度。
    • onProgressUpdate(Progress…) 此方法在主线程执行,用于显示任务执行的进度。
    • onPostExecute(Result) 此方法在主线程执行,任务执行的结果作为此方法的参数返回。

    举个简单的例子如下:
    // 设置三种类型参数分别为String,Integer,String
    class PageTask extends AsyncTask {
    // 可变长的输入参数,与AsyncTask.exucute()对应
    @Override
    protected String doInBackground(String… params) {
    try {
    HttpClient client = new DefaultHttpClient();
    // params[0]代表连接的url
    HttpGet get = new HttpGet(params[0]);
    HttpResponse response = client.execute(get);
    HttpEntity entity = response.getEntity();
    long length = entity.getContentLength();
    InputStream is = entity.getContent();
    String s = null;
    if (is != null) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    byte[] buf = new byte[128];
    int ch = -1;
    int count = 0;
    while ((ch = is.read(buf)) != -1) {
    baos.write(buf, 0, ch);
    count += ch;
    if (length > 0) {
    // 如果知道响应的长度,调用publishProgress()更新进度
    publishProgress((int) ((count / (float) length) * 100));
    }
    // 为了在模拟器中清楚地看到进度,让线程休眠100ms
    Thread.sleep(100);
    }
    s = new String(baos.toByteArray()); }
    // 返回结果
    return s;
    } catch (Exception e) {
    e.printStackTrace();
    }
    return null;
    }
    @Override
    protected void onCancelled() {
    super.onCancelled();
    }
    @Override
    protected void onPostExecute(String result) {
    // 返回HTML页面的内容
    message.setText(result);
    }
    @Override
    protected void onPreExecute() {
    // 任务启动,可以在这里显示一个对话框,这里简单处理
    message.setText(R.string.task_started);
    }
    @Override
    protected void onProgressUpdate(Integer… values) {
    // 更新进度
    message.setText(values[0]);
    }
    }
    执行PageTask非常简单,只需要调用如下代码。
    PageTask task = new PageTask();
    task.execute(url.getText().toString());

      评论这张
     
    阅读(212)| 评论(0)
    推荐 转载

    历史上的今天

    在LOFTER的更多文章

    评论

    <#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
     
     
     
     
     
     
     
     
     
     
     
     
     
     

    页脚

    网易公司版权所有 ©1997-2018