AsyncTask方便我们在子线程进行耗时操作,并且方便切换到UI线程进行更新UI,不需要再使用Handler等在子线程与主线程之间进行通信了。
AsyncTask的基本用法
AsyncTask是一个抽象类,因此使用它就要写一个类继承它,继承的时候需要指定三个泛型参数
- Params
在执行后台任务时需要传入的参数类型,doInbackground()方法的参数 - Progress
如果需要在界面上显示执行的任务进度,则使用这里指定的泛型指定的类型作为进度单位,onProgressUpdate()方法和publishProgress()方法的参数 - Return
任务执行完成后,如果需要返回值,就使用这里指定的泛型作为返回值的类型,doInbackground()方法的返回类型以及onPostExecute()方法的参数
重写他的几个方法,一个简单的AsyncTask就可以写成
class MyAsyncTask extends AsyncTask<Void, Integer, Boolean>{
@Override
protected void onPreExecute() {
// TODO Auto-generated method stub
super.onPreExecute();
}
@Override
protected Boolean doInBackground(Void... params) {
// TODO Auto-generated method stub
return null;
}
@Override
protected void onProgressUpdate(Integer... values) {
// TODO Auto-generated method stub
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Boolean result) {
// TODO Auto-generated method stub
super.onPostExecute(result);
}
}
重写的这四个方法为
- onPreExecute()
这个方法会在任务开始前进行调用,在这里可以执行一些准备工作,例如显示一个进度条等。 - doInbackground(Void…params)
执行任务的方法,这个方法是在子线程中执行的,因此可以执行一些耗时任务,执行完毕后需要用return语句进行返回,返回的类型就是继承AsyncTask时定义的第三个参数,如果定义为Void,则不需要返回,定义为Integer,就返回Integer类型。注意,由于该方法是在子线程中执行的,因此不可以更新UI,如果需要更新UI,应该调用publishProgress(Progress…)方法完成。 - onProgressUpdate(Integer…values)
当后台任务中调用了publishProgress(Progress…)方法后,这个方法很快便会被调用,方法中的参数就是publishProgress(Progress)方法传递进来的参数,该方法可以利用传递进来的参数更新UI,例如更新进度条的进度。 - onPostExecute(Boolean…result)
当后台任务执行完毕,通过return语句进行返回后,该方法马上会被调用,返回的结果作为参数传递到该方法中。在该方法中可以进行UI操作,例如提示任务完成,关闭进度条等。
使用实例(后台下载图片,并显示)
继承AsyncTask,泛型分别为URL,Integer,Boolean,说明下载任务需要传递一个URL参数,然后更新进度是Integer类型,返回结果是Boolean类型
class DownloadAsyncTask extends AsyncTask<URL, Integer, Boolean>
重写onPreExecute方法
在这里,定义了一个进度条,显示在主界面
@Override
//运行前的准备
protected void onPreExecute() {
dialog=new ProgressDialog(MainActivity.this);
dialog.setTitle("下载进度");
dialog.setMax(100);
dialog.setCancelable(true);
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
dialog.show();
}
重写doInbackground方法
传递进来需要下载的Url地址,然后通过HttpURLConnection访问网络,通过IO流进行下载图片,然后计算进度,由于图片太小,下载的太快,所以我在这里每读取一次byte[1024],就使线程休眠100毫秒,没读取一次就计算一次进度,然后publishProgress方法通知更新进度条
@Override
protected Boolean doInBackground(URL... params) {
HttpURLConnection connection=null;
int contentLenth=0;
try {
connection=(HttpURLConnection) params[0].openConnection();
connection.setConnectTimeout(4000);
connection.setReadTimeout(4000);
connection.setRequestMethod("GET");
contentLenth=connection.getContentLength();
File file=new File(getCacheDir()+"xu.jpg");
InputStream in=connection.getInputStream();
FileOutputStream out=new FileOutputStream(file);
byte[] b=new byte[1024];
int len=0;
int totalSize=0;
while((len=in.read(b))!=-1){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
out.write(b, 0, len);
totalSize+=len*100;
int progress=(totalSize/contentLenth);
publishProgress(progress);
}
} catch (IOException e) {
e.printStackTrace();
}
return true;
}
重写onProgressUpdate方法
通过publishProgress方法传递进来的进度更新进度条的进度。
@Override
protected void onProgressUpdate(Integer... values) {
dialog.setProgress(values[0]);
}
重写onPostExecute方法
如果返回的是true,就显示下载成功,并将图片显示出来通过BitmapFactory.decodeStream(file)方法得到一个Bitmap对象,然后显示在ImageView中。
@Override
protected void onPostExecute(Boolean result) {
dialog.dismiss();
if(result){
Toast.makeText(MainActivity.this, "下载成功", Toast.LENGTH_LONG).show();
File file=new File(getCacheDir()+"xu.jpg");
Bitmap bitmap=null;
try {
bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
mShowImageView.setImageBitmap(bitmap);
}else{
Toast.makeText(MainActivity.this, "下载失败", Toast.LENGTH_LONG).show();
}
}
调用执行
界面一打开,就开始下载,然后完成后在ImageView上显示
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mShowImageView=(ImageView) findViewById(R.id.main_show_ImageView);
try {
new DownloadAsyncTask().execute(new URL("https://ss0.bdstatic.com/94oJfD_bAAcT8t7mm9GUKT-xh_/timg?image&quality=100&size=b4000_4000&sec=1465108635&di=d36b371b3eeb89bf304ccfbee2b4f1cd&src=http://picture.youth.cn/dmzb/201305/W020130514542662922703.jpg"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}