安卓开发笔记——关于AsyncTask的使用
|
在安卓开发中,我们经常要进行一些耗时操作,比如数据库操作,获取网络资源,读取内存文件等等,当我们在处理这些耗时操作的时候,如果我们直接在UI主线程进行,那么可能会导致阻塞UI主线程,使得UI界面卡顿,带来很不好的用户体验,因此安卓也给我们提供了2个异步操作的类,Handler和AsyncTask。 今天先讲AsyncTask,AsyncTask类是Andorid提供给我们的一个轻量级异步类,算是一个框架,它对线程之间的通讯进行了封装,并且提供了简易的编程操作,使得我们可以很轻松的实现后台线程和UI主线程之间的通讯。 我写了一个异步获取网络图片的小例子,先来看实现效果:
?
以上是官网对AsyncTask的一些描述,大致意思是: AsyncTask是一个易操作线程使用类,它可以帮助我们把后台线程处理程序的结果发送给UI主线程,使UI线程得到更新。 AsyncTask类提供了3个泛型参数(Params,Progress,Result)和4个执行步骤(下文会具体提及) ? 先来看下3个泛型参数
1、Params:这是一个任务参数,一般我们会定义成String类型的,例如本例子中要获取网络资源的URL地址 2、Progress:任务执行的刻度,一般我们会定义成Integer类型 3、Result:返回结果类型,例如本例中是对网络图片进行获取,那么它的返回类型应该是BitMap ? 再来看下4个步骤:
当我们的类去实现AsyncTask类的时候至少需要实现doInBackground(Params...)方法,这里作为学习,我把每一个的具体工作任务也说说 它的执行顺序是这样的?onPreExecute-->doInBackground-->onProgressUpdate-->onPostExecute 1、onPreExecute:这是一个预处理方法,在任务开始的时候执行,我们可以在这里进行一些控件的实例化,设置属性等。(非必须) 2、doInBackground:这是一个任务操作方法,也是最重要的一个方法,所有的耗时操作都应该在这里执行。(必须) 3、onProgressUpdate:这是一个进度即时更新方法,在这里我们可以即时更新任务滚动条的进度。(非必须,当在doInBackground里调用publishProgress时触发) 4、onPostExecute:这是一个任务结果处理方法,在doInBackground里执行完任务,会将结果通知给这个类,在这类中我们可以对UI进行更新操作(非必须) 上面的1、3、4是UI主线程触发调用的,所以可以对UI进行更新操作,而第2步是个异步操作,不能在里面进行UI的更新操作。 ?
关于AsyncTask的调用,其实非常简单,我们在AsyncTask类被继承实现的时候,在主线程直接对其对象调用execute(Params..)方法即可。 ? 好了,文字介绍到此结束,上代码: 1、布局文件 1 <LinearLayout xmlns:android@H_403_95@="http://schemas.android.com/apk/res/android" @H_403_95@ 2 xmlns:tools@H_403_95@="http://schemas.android.com/tools" @H_403_95@ 3 android:layout_width@H_403_95@="match_parent" @H_403_95@ 4 android:layout_height@H_403_95@="match_parent" @H_403_95@ 5 android:gravity@H_403_95@="center" @H_403_95@ 6 android:orientation@H_403_95@="vertical"@H_403_95@> @H_403_95@ 7 @H_403_95@ 8 @H_403_95@ImageView @H_403_95@ 9 android:id@H_403_95@="@+id/imageView" @H_403_95@10 android:layout_width@H_403_95@="wrap_content" @H_403_95@11 android:layout_height@H_403_95@="wrap_content" @H_403_95@/> @H_403_95@12 @H_403_95@13 @H_403_95@Button @H_403_95@14 ="@+id/bt_download" @H_403_95@15 16 17 android:text@H_403_95@="下载图片" @H_403_95@18 @H_403_95@19 @H_403_95@</LinearLayout@H_403_95@> ? 2、AsyncTask的实现类 @H_403_95@ 1 @H_403_95@package@H_403_95@ com.example.asynctasktest;
@H_403_95@ 2
@H_403_95@ 3 @H_403_95@import@H_403_95@ java.io.ByteArrayOutputStream;
@H_403_95@ 4 @H_403_95@ java.io.IOException;
@H_403_95@ 5 @H_403_95@ java.io.InputStream;
@H_403_95@ 6 @H_403_95@ java.io.OutputStream;
@H_403_95@ 7
@H_403_95@ 8 @H_403_95@ org.apache.http.HttpResponse;
@H_403_95@ 9 @H_403_95@ org.apache.http.client.ClientProtocolException;
@H_403_95@ 10 @H_403_95@ org.apache.http.client.HttpClient;
@H_403_95@ 11 @H_403_95@ org.apache.http.client.methods.HttpGet;
@H_403_95@ 12 @H_403_95@ org.apache.http.impl.client.DefaultHttpClient;
@H_403_95@ 13
@H_403_95@ 14 @H_403_95@ android.app.ProgressDialog;
@H_403_95@ 15 @H_403_95@ android.graphics.Bitmap;
@H_403_95@ 16 @H_403_95@ android.graphics.BitmapFactory;
@H_403_95@ 17 @H_403_95@ android.os.AsyncTask;
@H_403_95@ 18 @H_403_95@ android.widget.ImageView;
@H_403_95@ 19
@H_403_95@ 20 @H_403_95@public @H_403_95@class MyAsyncTask @H_403_95@extends AsyncTask<String,Integer,Bitmap>@H_403_95@ {
@H_403_95@ 21
@H_403_95@ 22 @H_403_95@private@H_403_95@ ImageView imageView;
@H_403_95@ 23 @H_403_95@ ProgressDialog progressDialog;
@H_403_95@ 24
@H_403_95@ 25 @H_403_95@public@H_403_95@ MyAsyncTask(ImageView imageView,ProgressDialog progressDialog) {
@H_403_95@ 26 @H_403_95@this.imageView =@H_403_95@ imageView;
@H_403_95@ 27 @H_403_95@this.progressDialog =@H_403_95@ progressDialog;
@H_403_95@ 28 @H_403_95@ }
@H_403_95@ 29
@H_403_95@ 30 @H_403_95@/**
@H_403_95@ 31 @H_403_95@ * 执行第一步 这里为预处理操作,被UI线程所调用(可以在这里完成进度条的属性设置)
@H_403_95@ 32 @H_403_95@*/
@H_403_95@ 33 @H_403_95@ @Override
@H_403_95@ 34 @H_403_95@protected @H_403_95@void@H_403_95@ onPreExecute() {
@H_403_95@ 35 @H_403_95@super@H_403_95@.onPreExecute();
@H_403_95@ 36 progressDialog.setTitle("当前任务"@H_403_95@);
@H_403_95@ 37 progressDialog.setMessage("正在下载图片,请稍后..."@H_403_95@ 38 progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);@H_403_95@//@H_403_95@设置进度条样式,横项
@H_403_95@ 39 @H_403_95@ progressDialog.show();
@H_403_95@ 40 @H_403_95@ 41
@H_403_95@ 42 @H_403_95@ 43 @H_403_95@ * 执行第二步 这里为异步线程,在这里处理耗时任务操作(比如:下载,读取文件)
@H_403_95@ 44 @H_403_95@ * 通过调用publishProgress方法(传递即时任务进度)可以触发onProgressUpdate的执行
@H_403_95@ 45 @H_403_95@ 46 @H_403_95@ 47 @H_403_95@protected@H_403_95@ Bitmap doInBackground(String... params) {
@H_403_95@ 48 String path=params[0@H_403_95@];
@H_403_95@ 49 Bitmap bitmap=@H_403_95@null@H_403_95@;
@H_403_95@ 50 HttpClient httpClient=@H_403_95@new@H_403_95@ DefaultHttpClient();
@H_403_95@ 51 HttpGet httpGet=@H_403_95@ HttpGet(path);
@H_403_95@ 52 InputStream inputStream=@H_403_95@ 53 @H_403_95@try@H_403_95@ {
@H_403_95@ 54 HttpResponse httpResponse=@H_403_95@httpClient.execute(httpGet);
@H_403_95@ 55 @H_403_95@if(httpResponse.getStatusLine().getStatusCode()==200@H_403_95@){
@H_403_95@ 56 @H_403_95@连接成功
@H_403_95@ 57 @H_403_95@ HttpEntity entity=httpResponse.getEntity();
@H_403_95@ 58 @H_403_95@ byte[] data=EntityUtils.toByteArray(entity);
@H_403_95@ 59 @H_403_95@ bitmap=BitmapFactory.decodeByteArray(data,data.length);
@H_403_95@ 60
@H_403_95@ 61 inputStream=@H_403_95@httpResponse.getEntity().getContent();
@H_403_95@ 62 ByteArrayOutputStream outputStream=@H_403_95@ ByteArrayOutputStream();
@H_403_95@ 63 @H_403_95@long fileSize=httpResponse.getEntity().getContentLength();@H_403_95@文件总大小
@H_403_95@ 64 @H_403_95@byte[] data=@H_403_95@new @H_403_95@byte[1024];@H_403_95@每次读取的大小
@H_403_95@ 65 @H_403_95@int len=0;@H_403_95@本次读取的大小
@H_403_95@ 66 @H_403_95@int total=0;@H_403_95@累计读取的大小
@H_403_95@ 67 @H_403_95@while((len=inputStream.read(data))!=-1@H_403_95@ 68 total+=len;@H_403_95@ 69 @H_403_95@int values=(@H_403_95@int) ((total/(@H_403_95@float)fileSize)*100);@H_403_95@得到当前任务进行百分比
@H_403_95@ 70 publishProgress(values);@H_403_95@触发onProgressUpdate更新即时进度
@H_403_95@ 71 outputStream.write(data,0@H_403_95@,len);
@H_403_95@ 72 @H_403_95@ }
@H_403_95@ 73 @H_403_95@byte[] result=outputStream.toByteArray();@H_403_95@转换为字节数组
@H_403_95@ 74 bitmap=BitmapFactory.decodeByteArray(result,result.length);
@H_403_95@ 75 @H_403_95@ }
@H_403_95@ 76 } @H_403_95@catch@H_403_95@ (ClientProtocolException e) {
@H_403_95@ 77 @H_403_95@ e.printStackTrace();
@H_403_95@ 78 } @H_403_95@ (IOException e) {
@H_403_95@ 79 @H_403_95@ 80 }@H_403_95@finally@H_403_95@{
@H_403_95@ 81 @H_403_95@if(inputStream!=@H_403_95@ 82 @H_403_95@ 83 @H_403_95@ inputStream.close();
@H_403_95@ 84 } @H_403_95@ 85 @H_403_95@ e.printStackTrace();
@H_403_95@ 86 @H_403_95@ 87 @H_403_95@ 88 @H_403_95@ }
@H_403_95@ 89
@H_403_95@ 90 @H_403_95@return@H_403_95@ bitmap;
@H_403_95@ 91
@H_403_95@ 92 @H_403_95@ 93
@H_403_95@ 94 @H_403_95@ 95 @H_403_95@ * 执行第三步 这里为实时UI更新操作,被UI线程所调用 在这里可以即时更新(如进度条进度)
@H_403_95@ 96 @H_403_95@ 97 @H_403_95@ 98 @H_403_95@ onProgressUpdate(Integer... values) {
@H_403_95@ 99 @H_403_95@.onProgressUpdate(values);
@H_403_95@100 progressDialog.setProgress(values[0@H_403_95@]);
@H_403_95@101 @H_403_95@102
@H_403_95@103 @H_403_95@104 @H_403_95@ * 执行第四步 在这里会返回doInBackground的操作结果,被UI线程调用,更新最后UI结果
@H_403_95@105 @H_403_95@106 @H_403_95@107 @H_403_95@ onPostExecute(Bitmap result) {
@H_403_95@108 @H_403_95@.onPostExecute(result);
@H_403_95@109 @H_403_95@ progressDialog.dismiss();
@H_403_95@110 @H_403_95@ imageView.setImageBitmap(result);
@H_403_95@111 @H_403_95@112
@H_403_95@113 }
? 3、主类 @H_403_95@ 2
@H_403_95@ 3 @H_403_95@ 4 @H_403_95@ android.os.Bundle;
@H_403_95@ 5 @H_403_95@ android.support.v7.app.ActionBarActivity;
@H_403_95@ 6 @H_403_95@ android.view.View;
@H_403_95@ 7 @H_403_95@ android.view.View.OnClickListener;
@H_403_95@ 8 @H_403_95@ android.widget.Button;
@H_403_95@ 9 @H_403_95@10
@H_403_95@11 @H_403_95@class MainActivity @H_403_95@extends@H_403_95@ ActionBarActivity {
@H_403_95@14 @H_403_95@ Button bt_download;
@H_403_95@15 @H_403_95@private ProgressDialog progressDialog;@H_403_95@进度对话框
@H_403_95@16 @H_403_95@private String path="http://img.pconline.com.cn/images/photoblog/5/3/7/5/5375781/20096/6/1244302842840.jpg";@H_403_95@下载图片路径
@H_403_95@17
@H_403_95@18 @H_403_95@19 @H_403_95@ onCreate(Bundle savedInstanceState) {
@H_403_95@20 @H_403_95@.onCreate(savedInstanceState);
@H_403_95@21 @H_403_95@ setContentView(R.layout.activity_main);
@H_403_95@22
@H_403_95@23 imageView=@H_403_95@(ImageView) findViewById(R.id.imageView);
@H_403_95@24 bt_download=@H_403_95@(Button) findViewById(R.id.bt_download);
@H_403_95@25 progressDialog=@H_403_95@new ProgressDialog(@H_403_95@this@H_403_95@26
@H_403_95@27 bt_download.setOnClickListener(@H_403_95@ OnClickListener() {
@H_403_95@28
@H_403_95@29 @H_403_95@ @Override
@H_403_95@30 @H_403_95@ onClick(View v) {
@H_403_95@31 MyAsyncTask myAsyncTask=@H_403_95@ MyAsyncTask(imageView,progressDialog);
@H_403_95@32 @H_403_95@ myAsyncTask.execute(path);
@H_403_95@33 @H_403_95@34 @H_403_95@ });
@H_403_95@35
@H_403_95@36 @H_403_95@37
@H_403_95@38
@H_403_95@39 }
? 代码到此结束,注释很详细应该很好理解。 使用AsyncTask类,以下是几条必须遵守的准则:
当然AsyncTask类不止这些东西,还有线程池的概念,今天先不讲,过几天连同Handler一起说。 对于简单的异步操作,掌握这些已经够了。 ? 项目代码:http://pan.baidu.com/s/1kTkTgm7 ? 作者:Balla_兔子 ? (编辑:北几岛) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |





