AsyncTask的简单例子
使用场景
使用AsyncTask可以方便的执行后台任务并且将后台任务的执行结果显示在UI上。你不需要操作Thread或Handler就可以完成耗时任务并且将操作结果显示在UI上。
AsyncTask通用参数说明
AsyncTask使用如下三个通用参数:
- Params, 通过execution将参数传递给该任务.
- Progress, 进度单位类型.
- Result, 结果类型.
如果你不想使用某个参数,直接使用Void即可。
AsyncTask的四个步骤
- onPreExecute(), 在AsyncTask执行之前在UI线程上执行,主要是做一些任务初始化工作。
- doInBackground(Params…),在onPreExecute()执行之后会立即启动后台线程来执行该回调函数,该回调函数主要完成一些耗时操作。如果需要,你可以在该回调函数中调用 publishProgress (Progress… values)来上报进度信息,该进度信息由onProgressUpdate(Progress…) 接收并处理,这里需要注意的是onProgressUpdate(Progress…) 是在UI界面执行的,所以可以修改UI的属性。
- onProgressUpdate(Progress…),在publishProgress(Progress…)函数执行调用之后在UI线程里运行该回调函数。主要是用来更新进度信息并显示在Log或者UI上。
- onPostExecute(Result),当后台任务完成之后UI线程会回调该函数。该函数在UI线程里运行,所以可以修改UI属性。
使用AsyncTask需要遵守如下规则
- 必须在UI线程初始化并运行AsyncTask
- 不要手动调用 onPreExecute(), onPostExecute(Result), doInBackground(Params…), onProgressUpdate(Progress…)
- 该AsyncTask只能执行一次(如果执行多次会抛出一个异常)
本文的例子非常简单,使用AsyncTask从网上下载一个图片,然后将图片显示在ImageView里。同时将图片下载进度用进度条(ProgressBar)显示出来,当然这里只是模拟下载进度,实际上一个图片下载耗时很短,人眼很难看见实际的进度变化。
1.定义两个button,一个ImageView和一个ProgressBar。其中一个按钮用例启动图片下载,另一个取消图片下载。ImageView用来显示从网络上下载下来的图片,ProgressBar用来显示图片下载进度。
2.在AsyncTaskApp上我们主要实例化了ImageView和ProgressBar,并将这两个实例传给DownloadImage的构造函数生成DownloadImage实例。通过点击Download按钮来下载图片,通过点击cancel按钮来取消图片下载。
初始化
progressBar = (ProgressBar)findViewById(R.id.progressBar);
imageView = (ImageView)findViewById(R.id.imageView);
downloadImage = new DownloadImage(imageView, progressBar);
图片下载按钮
public void onDownload(View view)
{
if(!start) {
start = true;
Log.i("information", "onDownload");
downloadImage.execute("http://www.baidu.com/img/bd_logo1.png");
}
}
图片下载取消
public void onCancel(View view)
{
downloadImage.cancel(true);
}
3.所有图片下载和进度显示以及图片显示在ImageView上都是通过DownloadImage类完成。
DownloadImage初始化
private int progress;
private ImageView imageView;
private ProgressBar progressBar;
private static int MAX = 100;
public DownloadImage(ImageView imageview, ProgressBar progressBar)
{
this.imageView = imageview;
this.progressBar = progressBar;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
Log.i("information", "onPreExecute");
progress = 0;
}
下载图片
private Bitmap downloadImage(String imageUrl)
{
Bitmap bitmap = null;
try {
URL url = new URL(imageUrl);
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setDoInput(true);
conn.connect();
InputStream is = conn.getInputStream();
bitmap = BitmapFactory.decodeStream(is);
}catch (Exception e)
{
e.printStackTrace();
}
return bitmap;
}
@Override
protected Bitmap doInBackground(String... params) {
Log.i("information", "doInBackground");
Bitmap bitmap = downloadImage(params[0]);
while(progress < MAX)
{
if(isCancelled())
{
return null;
}
publishProgress(progress);
progress++;
SystemClock.sleep(200);
}
return bitmap;
}
进度更新
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
Log.i("information", "onProgressUpdate");
progressBar.setProgress(values[0]);
}
图片显示
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
Log.i("information", "onPostExecute");
imageView.setImageBitmap(bitmap);
}
取消下载
@Override
protected void onCancelled(Bitmap bitmap) {
super.onCancelled(bitmap);
Log.i("information", "onCancelled");
}