AsyncTask
什么是AsyncTask
AsyncTask是一个轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行的进度和结果传递给主线程并在主线程中更新UI。
AsyncTask这个类的声明如下
public abstract class AsyncTask<Params, Progress, Result>
它提供了Params, Progress和 Result三个泛型参数,在下面会仔细分析这三个泛型参数的具体含义。
AsyncTask提供了四个核心方法
onPreExecute()
此方法在主线程中执行,在异步任务执行之前,此方法会被调用,一般用于一些准备工作,例如下载进度条的初始化。doInBackground(Params… params)
此方法在子线程中执行,用于执行异步任务,注意这里的params就是AsyncTask的第一个参数类型。在此方法中可以通过调用publicProgress方法来更新任务进度,publicProgress会调用onProgressUpdate方法。onProgressUpdate(Progress… values)
此方法在主线程中执行,values的类型就是AsyncTask传入的第二个参数类型,当后台任务的执行进度发生变化时此方法执行。onPostExecute(Result result)
此方法在主线程中执行,在doInBackground方法执行完成以后此方法会被调用,其中result的类型就是AsyncTask传入的第三个参数类型,它的值就是doInBackground方法的返回值。
接着还是看一下AsyncTask最常见的用法,该事例就是下载一张图片到手机内存的cache目录下,下载开始时会弹出进度框,在下载过程中显示下载的进度,下载完成后关闭进度框,如成功则出现下载成功的Toast,失败则弹出失败的Toast。
class MyAsyncTask extends AsyncTask<Void,Integer,Boolean> {
@Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setTitle("下载进度");
progressDialog.setMax(100);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setCancelable(true);
progressDialog.show();
}
@Override
protected Boolean doInBackground(Void... params) {
HttpURLConnection conn = null;
try {
conn = (HttpURLConnection) params[0].openConnection();
conn.setRequestMethod("GET");
conn.setConnectTimeout(5000);
conn.setReadTimeout(5000);
final int contentLength;
if (conn.getResponseCode() == 200) {
contentLength = conn.getContentLength();
File file = new File(getCacheDir(),"hh.jpg");
InputStream is= null;
FileOutputStream fos= new FileOutputStream(file);
is = conn.getInputStream();
int len = 0;
long totalSize = 0;
byte[] bytes = new byte[102];
while ((len = is.read(bytes))!=-1) {
fos.write(bytes,0,len);
totalSize += len*100;
int progress = (int) (totalSize/contentLength);
publishProgress(progress);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
@Override
protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress(values[0]);
}
@Override
protected void onPostExecute(Boolean aBoolean) {
progressDialog.dismiss();
i