AsyncTask<Params, Progress, Result> 是一个抽象类,通常用于被继承,继承 AsyncTask 时需要指定如下三个泛型参数。
Params :启动任务执行的输入参数的类型。
Progress :后台任务完成的进度值的类型。
Result :后台执行任务完成后返回结果的类型。
使用 AsyncTask 只要如下三步即可。
1、创建 AsyncTask 的子类,并为三个泛型参数指定类型。如果某个泛型参数不需要指定类型,则可将它指定为 Void 。
2、根据需要,实现 AsyncTask 的如下方法:
doInBackGround(Params...) :重写该方法就是后台线程将要完成的任务。该方法可以调用 publichProgress(Progress... values)
方法更新任务的执行进度。
onProgressUpdate(Progress... values) :在 doInBackGround() 方法中调用 publichProgress() 方法更新任务的执行进度后,将会
触发该方法。
onPreExecute() :该方法将在执行后台耗时操作前被调用。通常该方法用于完成一些初始化的准备工作,比如在界面上显示进
度条等。
onPostExecute(Result reault) :当 doInBackground() 完成后,系统会自动调用该方法,并将 doInBackground() 方法的返回值传
给该方法。
3、调用 AsyncTask 子类的实例的 execute(Params... params) 开始执行耗时任务。
使用 AsynvTask 时必须遵守如下规则。
必须在 UI 线程中创建 AsyncTask 的实例。
必须在 UI 线程中调用 AsyncTask 的execute() 方法。
AsyncTask 的 doInBackGround(Params...) 、onProgressUpdate(Progress... values) 、onPreExecute() 、onPostExecute(Result
reault) 方法,不应该由程序员代码调用,而是由 Android 系统负责调用。
每个 AsyncTask 只能被执行一次,多次调用将会引发异常。
接下来是一个执行下载任务的Demo,首先是效果图:
Java 代码:
public class MainActivity extends Activity {
private ImageView imageView;
private Button button;
private ProgressDialog progressDialog;
private MyAsyncTask asyncTask;
private final String IMAGE_PATH = "http://desk.fd.zol-img.com.cn/t_s960x600c5/g4/M01/0D/04/Cg-4WVP_npmIY6GRAKcKYPPMR3wAAQ8LgNIuTMApwp4015.jpg";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = (ImageView) findViewById(R.id.imageView);
button = (Button) findViewById(R.id.button);
progressDialog = new ProgressDialog(this);
progressDialog.setTitle("提示信息");
progressDialog.setMessage("正在下载...");
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(false);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
asyncTask = new MyAsyncTask();
asyncTask.execute(IMAGE_PATH);
}
});
}
private class MyAsyncTask extends AsyncTask<String, Integer, Bitmap> {
@Override
protected void onPreExecute() {
progressDialog.show();
}
@Override
protected Bitmap doInBackground(String... params) {
InputStream inputStream = null;
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Bitmap bitmap = null;
try {
URL url = new URL(params[0]);
URLConnection conn = url.openConnection();
// 建立链接
conn.connect();
// 获取输入流
inputStream = conn.getInputStream();
// 获取文件流大小,用于更新进度
long file_length = conn.getContentLength();
int len;
int total_length = 0;
byte[] data = new byte[1024];
while ((len = inputStream.read(data)) != -1) {
total_length += len;
int value = (int) ((total_length / (float) file_length) * 100);
// 调用update函数,更新进度
publishProgress(value);
outputStream.write(data, 0, len);
}
byte[] result = outputStream.toByteArray();
bitmap = BitmapFactory.decodeByteArray(result, 0, result.length);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return bitmap;
}
@Override
protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress(values[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
progressDialog.dismiss();
imageView.setImageBitmap(bitmap);
}
}
}