当第一次启动一个Android程序时,Android会自动创建一个称为“main”主线程的线程。这个主线程(也称为UI线程)很重要,因为它负责把事件分派到相应的控件,其中就包括屏幕绘图事件,它同样是用户与Andriod控件交互的线程。比如,当你在屏幕上按下一个按钮后,UI线程会把这个事件分发给刚按得那个按钮,紧接着按钮设置它自身为被按下状态并向事件队列发送一个无效(invalidate)请求。UI线程会把这个请求移出事件队列并通知按钮在屏幕上重新绘制自身。

Android单线程模型会在没有考虑到它的影响的情况下引起Android应用程序性能低下,因为所有的任务都在同一个线程中执行,如果执行一些耗时的操作,如访问网络或查询数据库,会阻塞整个用户界面。当在执行一些耗时的操作的时候,不能及时地分发事件,包括用户界面重绘事件。从用户的角度来看,应用程序看上去像挂掉了。更糟糕的是,如果阻塞应用程序的时间过长(现在大概是5秒钟)Android会向用户提示一些信息,即打开一个“应用程序没有相应(application not responding)”的对话框。在单线程模型中始终要记住两条法则:

不要阻塞UI线程

确保只在UI线程中访问Android UI工具包

Android之所以有Handler和AsyncTask,都是为了不阻塞主线程(UI线程),且UI的更新只能在主线程中完成,因此异步处理是不可避免的。
Android 1.5提供了一个工具类:AsyncTask,它使创建需要与用户界面交互的长时间运行的任务变得更简单。不需要借助线程和Handler即可实现。
AsyncTask 的优势体现在:
•线程的开销较大,如果每个任务都要创建一个线程,那么应用程 序的效率要低很多;
•线程无法管理,匿名线程创建并启动后就不受程序的控制了,如果有很多个请求发送,那么就会启动非常多的线程,系统将不堪重负。
•另外,前面已经看到,在新线程中更新UI还必须要引入handler,这让代码看上去非常臃肿。
AsyncTask定义了三种泛型类型 Params,Progress和Result。
    •Params 启动任务执行的输入参数,比如HTTP请求的URL。
    •Progress 后台任务执行的百分比。
    •Result 后台执行任务最终返回的结果,比如String。
AsyncTask的执行分为四个步骤,每一步都对应一个回调方法,开发者需要实现一个或几个方法。在任务的执行过程中,这些方法被自动调用。

子类化AsyncTask

实现AsyncTask中定义的下面一个或几个方法

onPreExecute(), 该方法将在执行实际的后台操作前被UI thread调用。可以在该方法中做一些准备工作,如在界面上显示一个进度条。
doInBackground(Params...), 将在onPreExecute 方法执行后马上执行,该方法运行在后台线程中。这里将主要负责执行那些很耗时的后台计算工作。可以调用 publishProgress方法来更新实时的任务进度。该方法是抽象方法,子类必须实现。
onProgressUpdate(Progress...),在publishProgress方法被调用后,UI thread将调用这个方法从而在界面上展示任务的进展情况,例如通过一个进度条进行展示。
onPostExecute(Result), 在doInBackground 执行完成后,onPostExecute 方法将被UI thread调用,后台的计算结果将通过该方法传递到UI thread.
使用AsyncTask类,以下是几条必须遵守的准则:
    1) Task的实例必须在UI thread中创建
    2) execute方法必须在UI thread中调用
    3) 不要手动的调用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)这几个方法
    4) 该task只能被执行一次,否则多次调用时将会出现异常

从网上获取一个网页,在一个TextView中将其源代码显示出来

  1. package test.list;
  2. import java.io.ByteArrayOutputStream;
  3. import java.io.InputStream;
  4. import java.util.ArrayList;
  5. import org.apache.http.HttpEntity;
  6. import org.apache.http.HttpResponse;
  7. import org.apache.http.client.HttpClient;
  8. import org.apache.http.client.methods.HttpGet;
  9. import org.apache.http.impl.client.DefaultHttpClient;
  10. import android.app.Activity;
  11. import android.app.ProgressDialog;
  12. import android.content.Context;
  13. import android.content.DialogInterface;
  14. import android.os.AsyncTask;
  15. import android.os.Bundle;
  16. import android.os.Handler;
  17. import android.os.Message;
  18. import android.view.View;
  19. import android.widget.Button;
  20. import android.widget.EditText;
  21. import android.widget.TextView;
  22. public class NetworkActivity extends Activity{
  23. private TextView message;
  24. private Button open;
  25. private EditText url;
  26. @Override
  27. public void onCreate(Bundle savedInstanceState) {
  28. super.onCreate(savedInstanceState);
  29. setContentView(R.layout.network);
  30. message= (TextView) findViewById(R.id.message);
  31. url= (EditText) findViewById(R.id.url);
  32. open= (Button) findViewById(R.id.open);
  33. open.setOnClickListener(new View.OnClickListener() {
  34. public void onClick(View arg0) {
  35. connect();
  36. }
  37. });
  38. }
  39. private void connect() {
  40. PageTask task = new PageTask(this);
  41. task.execute(url.getText().toString());
  42. }
  43. class PageTask extends AsyncTask<String, Integer, String> {
  44. // 可变长的输入参数,与AsyncTask.exucute()对应
  45. ProgressDialog pdialog;
  46. public PageTask(Context context){
  47. pdialog = new ProgressDialog(context, 0);
  48. pdialog.setButton("cancel", new DialogInterface.OnClickListener() {
  49. public void onClick(DialogInterface dialog, int i) {
  50. dialog.cancel();
  51. }
  52. });
  53. pdialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
  54. public void onCancel(DialogInterface dialog) {
  55. finish();
  56. }
  57. });
  58. pdialog.setCancelable(true);
  59. pdialog.setMax(100);
  60. pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
  61. pdialog.show();
  62. }
  63. @Override
  64. protected String doInBackground(String... params) {
  65. try{
  66. HttpClient client = new DefaultHttpClient();
  67. // params[0]代表连接的url
  68. HttpGet get = new HttpGet(params[0]);
  69. HttpResponse response = client.execute(get);
  70. HttpEntity entity = response.getEntity();
  71. long length = entity.getContentLength();
  72. InputStream is = entity.getContent();
  73. String s = null;
  74. if(is != null) {
  75. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  76. byte[] buf = new byte[128];
  77. int ch = -1;
  78. int count = 0;
  79. while((ch = is.read(buf)) != -1) {
  80. baos.write(buf, 0, ch);
  81. count += ch;
  82. if(length > 0) {
  83. // 如果知道响应的长度,调用publishProgress()更新进度
  84. publishProgress((int) ((count / (float) length) * 100));
  85. }
  86. // 让线程休眠100ms
  87. Thread.sleep(100);
  88. }
  89. s = new String(baos.toByteArray());              }
  90. // 返回结果
  91. return s;
  92. } catch(Exception e) {
  93. e.printStackTrace();
  94. }
  95. return null;
  96. }
  97. @Override
  98. protected void onCancelled() {
  99. super.onCancelled();
  100. }
  101. @Override
  102. protected void onPostExecute(String result) {
  103. // 返回HTML页面的内容
  104. message.setText(result);
  105. pdialog.dismiss();
  106. }
  107. @Override
  108. protected void onPreExecute() {
  109. // 任务启动,可以在这里显示一个对话框,这里简单处理
  110. message.setText(R.string.task_started);
  111. }
  112. @Override
  113. protected void onProgressUpdate(Integer... values) {
  114. // 更新进度
  115. System.out.println(""+values[0]);
  116. message.setText(""+values[0]);
  117. pdialog.setProgress(values[0]);
  118. }
  119. }
  120. }

转载于:https://www.cnblogs.com/sardine/archive/2011/07/29/2121587.html

AsyncTask应用解析相关推荐

  1. [学习总结]7、Android AsyncTask完全解析,带你从源码的角度彻底理解

    我们都知道,Android UI是线程不安全的,如果想要在子线程里进行UI操作,就需要借助Android的异步消息处理机制.之前我也写过了一篇文章从源码层面分析了Android的异步消息处理机制,感兴 ...

  2. AsyncTask源代码解析

    快要毕业了.近期在阿里巴巴校园招聘面试,一面过了,感觉挺轻松,可能是运气好.面试官感觉比我腼腆一些.我俩从android绕到了spring mvc 到数据库悲观锁 到linux 然后又会到了andro ...

  3. android asynctask,Android AsyncTask原理解析

    想要启动一个AsyncTask,首先需要创建一个AsyncTask对象然后调用execute方法.例如: new DownloadFilesTask().execute(); DownloadFile ...

  4. android asynctask 参数,Android AsyncTask 详细解析

    结构 继承关系 public abstract class AsyncTask extends Object java.lang.Object android.os.AsyncTask 类概述 Asy ...

  5. android activity启动流程_1307页!一线大厂Android面试全套真题解析!

    /   前言   / 金九银十到了,很多读者都反映有面试的需求,所以我特地给大家准备了一点资料! 下面的题目都是大家在面试一线互联网大厂时经常遇到的面试真题和答案解析,如果大家还有其他好的题目或者好的 ...

  6. 【Android 异步操作】AsyncTask 异步任务 ( 参数简介 | 方法简介 | 使用方法 | AsyncTask 源码分析 )

    文章目录 一.AsyncTask 参数简介 二.AsyncTask 方法简介 三.AsyncTask 基本用法 四.AsyncTask 构造函数源码解析 五.AsyncTask 构造函数相关源码注释 ...

  7. Android开发之异步消息处理机制AsyncTask

    转自:Android AsyncTask完全解析,带你从源码的角度彻底理解 另外一篇比较详细的博文:http://blog.csdn.net/liuhe688/article/details/6532 ...

  8. AsyncTask异步任务

    3.7 AsyncTask异步任务 分类 Android 基础入门教程 本节引言: 本节给大家带来的是Android给我们提供的一个轻量级的用于处理异步任务的类:AsyncTask,我们一般是 继承A ...

  9. AsyncTask原理

    为什么要用AsyncTask 我们知道,Android应用的主线程(UI 线程,是线程不安全的,负责前台用户界面的绘制以及响应用户的操作)肩负着绘制用户界面和及时响应用户操作的重任,为了避免" ...

最新文章

  1. NMAP分布式扫描工具dnmap
  2. 深入Mysql,SqlServer,Oracle主键自动增长的设置详解
  3. boost::lockfree::queue用法的测试程序
  4. Struts 2基础入门
  5. ios中base64编码
  6. python二维列表做参数_python sum函数iterable参数为二维list,start参数为“[]”该如何理解...
  7. 有关于iphone 音频 录制 播发
  8. tab控件的使用心得
  9. 深入理解javascript中的焦点管理
  10. 数学:深入浅出通信原理(陈爱军)
  11. Delphi开发工具的使用
  12. NameNode故障处理之数据恢复
  13. 服务器管理口IP及账号密码(知识汇总)
  14. 幻方解法之horse法生成奇阶幻方
  15. sdut-3386 小雷的冰茶几
  16. EXCEL应用:数据可视化终极教程
  17. 浙大计算机学院博士毕业论文要求,浙大在读博士需要3篇SCI 论文才能毕业,清华博士却不作要求!...
  18. 防黑客专家-MCK CBS
  19. MDN和IMSI码详细解释
  20. The Sandbox 与 Knights of Degen 达成合作,在元宇宙建立王国

热门文章

  1. 面向对象网络编程基础 property的使用
  2. 爬取小说 spider
  3. SQL Server会话KILL不掉,一直处于KILLED /ROLLBACK状态情形浅析
  4. 浏览器缓存:强缓存和协商缓存
  5. Node.js 框架
  6. Java序列化和克隆
  7. 《算法进阶指南》最小生成树剩余题目
  8. Ubuntu 16.04下如何安装VMware-Workstation
  9. jee websocket搭建总结
  10. 关于bjam编译自己模块出错的问题