AsyncTask
AsyncTask,异步任务,可以简单进行异步操作,并把执行结果发布到UI主线程。AsyncTask是一个抽象类,它的内部其实也是结合了Thread和Handler来实现异步线程操作,但是它形成了一个通用线程框架,更清晰简单。AsyncTask应该被用于比较简短的操作(最多几秒钟)。如果需要保持长时间运行的线程,可以使用ThreadPooExecutor或者FutureTask,关于这两个类的内容,以后再介绍,本片博客主要介绍AsyncTask。
AsyncTask被定义为一个操作,运行在一个后台线程中,其结果被发布在UI线程上。它的异步工作的参数与返回值被泛型的三个参数指定:Params、Progress、Result。AsyncTask将经历4个步骤:onPreExecute、doInBackground、onProgressUpdate、onPostExecute。下面详细讲解这三个参数与四个步骤:
三个泛型参数:
一个异步任务将经历四个阶段:
上面介绍的四个步骤的示意图:
AsyncTask取消任务
在程序的任何位置,都可以通过cancel(boolean)方法进行取消任务,当取消任务之后,会改变isCancelled()的返回值,使其返回true。之后会调用onCancelled(Object)方法,替代onPostExecute()得到doInBackground()的返回结果。在运行中,可以经常通过isCancelled()方法查看任务是否被取消。
AsyncTask的使用规则
使用AsyncTask必须遵循以下规则:
示例
一个简单的示例,通过AsyncTask下载一个网络上的图片,下载的时候展示一个等待框,并显示在一个ImageView中。
实现代码:
%201%20package%20com.bgxt.datatimepickerdemo; %202%20 %203%20import%20org.apache.http.HttpEntity; %204%20import%20org.apache.http.HttpResponse; %205%20import%20org.apache.http.client.HttpClient; %206%20import%20org.apache.http.client.methods.HttpGet; %207%20import%20org.apache.http.impl.client.DefaultHttpClient; %208%20import%20org.apache.http.util.EntityUtils; %209%20 10%20import%20android.app.Activity; 11%20import%20android.app.ProgressDialog; 12%20import%20android.graphics.Bitmap; 13%20import%20android.graphics.BitmapFactory; 14%20import%20android.os.AsyncTask; 15%20import%20android.os.Bundle; 16%20import%20android.view.View; 17%20import%20android.widget.Button; 18%20import%20android.widget.ImageView; 19%20 20%20public%20class%20AsyncTaskActivity1%20extends%20Activity%20{ 21%20%20%20%20%20private%20Button%20btnDown; 22%20%20%20%20%20private%20ImageView%20ivImage; 23%20%20%20%20%20private%20static%20String%20image_path%20=%20"http://ww4.sinaimg.cn/bmiddle/786013a5jw1e7akotp4bcj20c80i3aao.jpg"; 24 private ProgressDialog dialog; 25 26 @Override 27 protected void onCreate(Bundle savedInstanceState) { 28 // TODO Auto-generated method stub 29 super.onCreate(savedInstanceState); 30 setContentView(R.layout.asynctask_activity); 31 32 btnDown = (Button) findViewById(R.id.btnDown); 33 ivImage = (ImageView) findViewById(R.id.ivSinaImage); 34 35 // 声明一个等待框以提示用户等待 36 dialog=new ProgressDialog(this); 37 dialog.setTitle("提示信息"); 38 dialog.setMessage("正在下载,请稍后..."); 39 40 btnDown.setOnClickListener(new View.OnClickListener() { 41 42 @Override 43 public void onClick(View v) { 44 // 执行一个异步任务,并把图片地址以参数的形式传递进去 45 new MyTask().execute(image_path); 46 } 47 }); 48 } 49 50 // 以String类型的参数,Void表示没有进度信息,Bitmap表示异步任务返回一个位图 51 public class MyTask extends AsyncTask<String, Void, Bitmap> { 52 // 表示任务执行之前的操作 53 @Override 54 protected void onPreExecute() { 55 super.onPreExecute(); 56 //显示等待框 57 dialog.show(); 58 } 59 60 //主要是完成耗时操作 61 @Override 62 protected Bitmap doInBackground(String... params) { 63 HttpClient httpClient=new DefaultHttpClient(); 64 HttpGet httpGet=new HttpGet(params[0]); 65 Bitmap bitmap=null; 66 try { 67 //从网络上下载图片 68 HttpResponse httpResponse =httpClient.execute(httpGet); 69 if(httpResponse.getStatusLine().getStatusCode()==200){ 70 HttpEntity httpEntity = httpResponse.getEntity(); 71 byte[] data=EntityUtils.toByteArray(httpEntity); 72 bitmap=BitmapFactory.decodeByteArray(data, 0, data.length); 73 } 74 } catch (Exception e) { 75 e.printStackTrace(); 76 } 77 return bitmap; 78 } 79 80 //完成更新UI操作 81 @Override 82 protected void onPostExecute(Bitmap result) { 83 // TODO Auto-generated method stub 84 super.onPostExecute(result); 85 //设置ImageView的显示图片 86 ivImage.setImageBitmap(result); 87 // 销毁等待框 88 dialog.dismiss(); 89 } 90 91 } 92 }
效果展示:
上面的Demo并没有用到进度的信息,下面再提供一个完整的AsyncTask的Demo,同样是下载一个图片,并且展示到一个ImageView中,但是这里在下载的过程中增加一个进度条对话框,用于展示下载的进度。
实现代码:
%20%201%20package%20com.bgxt.datatimepickerdemo; %20%202%20 %20%203%20import%20java.io.ByteArrayOutputStream; %20%204%20import%20java.io.InputStream; %20%205%20 %20%206%20import%20org.apache.http.HttpResponse; %20%207%20import%20org.apache.http.client.HttpClient; %20%208%20import%20org.apache.http.client.methods.HttpGet; %20%209%20import%20org.apache.http.impl.client.DefaultHttpClient; %2010%20 %2011%20import%20android.app.Activity; %2012%20import%20android.app.ProgressDialog; %2013%20import%20android.graphics.Bitmap; %2014%20import%20android.graphics.BitmapFactory; %2015%20import%20android.os.AsyncTask; %2016%20import%20android.os.Bundle; %2017%20import%20android.view.View; %2018%20import%20android.widget.Button; %2019%20import%20android.widget.ImageView; %2020%20 %2021%20public%20class%20AsyncTaskActivity2%20extends%20Activity%20{ %2022%20%20%20%20%20private%20Button%20btnDown; %2023%20%20%20%20%20private%20ImageView%20ivImage; %2024%20%20%20%20%20private%20static%20String%20image_path%20=%20