AsyncTask的介绍与使用

1.AsyncTask的介绍
AsyncTask:异步任务,从字面上来说,就是在UI主线程运行的时候,异步完成一些操作。AsyncTask允许我们在后台执行一个异步任务。我们可以将耗时的操作放在异步任务当中来执行,并随时将任务执行的结果返回给UI线程来更新UI控件。通过AsyncTask我们可以轻松解决多线程之间的通信问题。

AsyncTask相当于Android给我们提供了一个多线程编程的一个框架,其介于Thread和Handler之间,我们如果要定义一个AsyncTask,就需要定义一个类来继承AsyncTask这个抽象类,并实现其唯一的一个 doInBackgroud 抽象方法。

AsyncTask总结起来就是: 3个泛型,4个步骤。

我们来看看AsyncTask这个抽象类的定义,当我们定义一个类来继承AsyncTask这个类的时候,需要为其指定3个泛型参数:

AsyncTask <Params, Progress, Result>
Params: 指定的是我们传递给异步任务执行时的参数的类型
Progress: 指定的是我们的异步任务在执行的时候将执行的进度返回给UI线程的参数的类型
Result: 指定的是异步任务执行完后返回给UI线程的结果的类型
我们在定义一个类继承AsyncTask类的时候,必须指定好这三个泛型的类型,如果都不指定的话,则都将其写成Void,例如:
AsyncTask <Void, Void, Void>

4个步骤:当我们执行一个异步任务时,需要按照下面的4个步骤分别执行:

onPreExecute(): 这个方法是在执行异步任务之前的时候执行,并且是在UI Thread当中执行的,通常我们在这个方法里做一些UI控件的初始化的操作,例如弹出ProgressDialog
doInBackground(Params... params): 在onPreExecute()方法执行完后,会马上执行这个方法,这个方法就是来处理异步任务的方法,Android操作系统会在后台的线程池当中开启一个worker thread来执行这个方法(即在worker thread当中执行),执行完后将执行结果发送给最后一个 onPostExecute 方法,在这个方法里,我们可以从网络当中获取数据等一些耗时的操作
onProgressUpdate(Progess... values): 这个方法也是在UI Thread当中执行的,在异步任务执行的时候,有时需要将执行的进度返回给UI界面,例如下载一张网络图片,我们需要时刻显示其下载的进度,就可以使用这个方法来更新进度。这个方法在调用之前,我们需要在 doInBackground 方法中调用一个 publishProgress(Progress) 的方法来将进度时时刻刻传递给 onProgressUpdate 方法来更新
onPostExecute(Result... result): 当异步任务执行完之后,就会将结果返回给这个方法,这个方法也是在UI Thread当中调用的,我们可以将返回的结果显示在UI控件上
为什么AsyncTask抽象类只有一个 doInBackground 的抽象方法呢??原因是,我们如果要做一个异步任务,我们必须要为其开辟一个新的Thread,让其完成一些操作,而在完成这个异步任务时,我可能并不需要弹出ProgressDialog,并不需要随时更新ProgressDialog的进度条,也并不需要将结果更新给UI界面,所以除了 doInBackground 方法之外的三个方法,都不是必须有的,因此必须要实现的方法是 doInBackground 方法。

4个步骤简洁版描述如下:

  第一步:表示任务执行前的操作

  第二步:主要完成耗时操作

  第三步:主要是更新UI操作

  第四步:产生最终结果

以下实例中代表的含义为:

  第一步:显示进度条

  第二步:(此任务必不可少)在后台执行任务,将进度值传给第三步,将结果传给第四步;

  第三步:进度值更新

  第四步:产生最终结果


2.AsyncTask从网络上下载一张图片,例子
public class MainActivity extends Activity {
25
26 private ImageView imageView ;
27 private Button button ;
28 private ProgressDialog dialog ;
29 //来自网络的图片
30 private String image_path = "http://imgsrc.baidu.com/forum/pic/item/7c1ed21b0ef41bd51a5ac36451da81cb39db3d10.jpg" ;
31 @Override
32 protected void onCreate(Bundle savedInstanceState) {
33 super.onCreate(savedInstanceState);
34 setContentView(R.layout.activity_main);
35
36 //添加弹出的对话框
37 dialog = new ProgressDialog(this) ;
38 dialog.setTitle("提示") ;
39 dialog.setMessage("正在下载图片,请稍后···") ;
40 //将进度条设置为水平风格,让其能够显示具体的进度值
41 dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL) ;
42 dialog.setCancelable(false) ; //用了这个方法之后,直到图片下载完成,进度条才会消失(即使在这之前点击了屏幕)
43
44 imageView = (ImageView)findViewById(R.id.imageView1) ;
45 button = (Button)findViewById(R.id.button1) ;
46 button.setOnClickListener(new OnClickListener() {
47
48 @Override
49 public void onClick(View v) {
50 //点击按钮时,执行异步任务的操作
51 new DownTask().execute(image_path) ;
52 }
53 }) ; //注意,这个地方的分号容易遗忘
54
55 }
56
57
58 /*
59 * 异步任务执行网络下载图片
60 * */
61 public class DownTask extends AsyncTask<String, Integer, byte[]> {
62 //上面的方法中,第一个参数:网络图片的路径,第二个参数的包装类:进度的刻度,第三个参数:任务执行的返回结果
63 @Override
64 //在界面上显示进度条
65 protected void onPreExecute() {
66 dialog.show() ;
67 };
68
69 protected byte[] doInBackground(String... params) { //三个点,代表可变参数
70 //使用网络链接类HttpClient类完成对网络数据的提取,即完成对图片的下载功能
71 HttpClient httpClient = new DefaultHttpClient() ;
72 HttpGet httpget = new HttpGet(params[0]) ;
73 byte[] result = null ;
74 ByteArrayOutputStream outputStream = new ByteArrayOutputStream() ;
75 InputStream inputStream = null ;
76
77 try {
78 HttpResponse httpResponse = httpClient.execute(httpget) ;
79 if(httpResponse.getStatusLine().getStatusCode()==200){
80
81 HttpEntity httpEntiry = httpResponse.getEntity();
82 inputStream = httpEntiry.getContent();
83 // 先要获得文件的总长度
84 long file_length = httpResponse.getEntity().getContentLength() ;
85 int len = 0 ;
86 // 每次读取1024个字节
87 byte[] data = new byte[1024] ;
88 // 每次读取后累加的长度
89 int total_length = 0 ;
90 while ((len = inputStream.read(data))!=-1) {
91 // 每读一次,就将total_length累加起来
92 total_length+=len ;
93 // 得到当前图片下载的进度
94 int progress_value = (int) ((total_length / (float)file_length)*100);
95 // 时刻将当前进度更新给onProgressUpdate方法
96 publishProgress(progress_value) ;
97 outputStream.write(data, 0, len);
98 }
99 // 边读边写到ByteArrayOutputStream当中
100 result = outputStream.toByteArray();
101 //bitmap = BitmapFactory.decodeByteArray(result, 0, result.length) ;
102 }
103 } catch (Exception e) {
104 // TODO Auto-generated catch block
105 e.printStackTrace();
106 } finally {
107 httpClient.getConnectionManager().shutdown();
108 }
109 return result;
110 }
111
112 @Override
113 protected void onProgressUpdate(Integer... values) {
114 // TODO Auto-generated method stub
115 super.onProgressUpdate(values);
116 // 更新ProgressDialog的进度条
117 dialog.setProgress(values[0]);
118 }
119
120 //主要是更新UI
121 @Override
122 protected void onPostExecute(byte[] result) {
123 super.onPostExecute(result);
124 // 将doInBackground方法返回的byte[]解码成要给Bitmap
125 Bitmap bitmap = BitmapFactory.decodeByteArray(result, 0, result.length) ;
126 // 更新我们的ImageView控件
127 imageView.setImageBitmap(bitmap) ;//更新UI
128 // 使ProgressDialog框消失
129 dialog.dismiss() ;
130 }
131 }
132
133 @Override
134 public boolean onCreateOptionsMenu(Menu menu) {
135 // Inflate the menu; this adds items to the action bar if it is present.
136 getMenuInflater().inflate(R.menu.main, menu);
137 return true;
138 }
139
140 }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值