类AsyncTask<Params, Progress, Result> 是java.lang.Object的子类,属于android.os包。
AsyncTask允许我们适当、简单的使用UI线程。我们可以使用它执行后台操作,在不使用线程或Handler的条件下发布结果到UI线程。
一个异步的任务被执行与后台的线程所定义,并将执行结果返回给UI线程。它包含三个泛型,分别是Params(参数),Progress(进度),Result(结果)。包含四个步骤:开始,doInBackground(后台执行),processProgress,结束。
1、用法
AsyncTask必须被继承来使用。子类必须重写它的至少一个方法doInBackground(Params...),而且经常也会重写这个方法onPostExecute(Result),请看下面这个例子:
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long>{
protected Long doInBackground(URL... urls){
int count = urls.length;
long totalSize = 0;
for(int i=0;i<count;i++){
totalSize += Downloader.downloadFiles(urls[i]);
publishProgress((int)((i/(float)count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress){
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result){
showDialog("Downloaded " + result + "bytes");
}
}
当类创建完后,执行就很简单了:
new DownloadFilesTask().execute(url1, url2, url3);
2、AsyncTask的泛型
一个异步任务所使用的三种类型如下:
1)Params,执行时传递给Task的参数类型;
2)Progress,在后台任务执行时所发布的进度值得类型;
3)Result,后台执行结果的类型;
一个异步任务并不是总是同时使用这三种类型,为了标志不用的类型,我们可以简单的使用Void标志。
3、四个步骤
当一个异步任务执行的时候,它会顺序执行这四个步骤:
1)onPreExecute()
执行于UI线程。在任务被执行后会立即在UI线程被激发执行。这一步经常用来为启动这个异步任务做准备,例如在用户界面显示一个进度条。
2)doInBackground(Params...)
执行于工作线程(非UI线程)。在onPreExecute()方法执行完后会立即在后台线程执行。这一步用来在后台执行一些耗时的操作。异步任务的参数传递到这个方法中。执行的结果必须有这一步返回,并传给最后一个方法。在这个方法中我们能使用publishProgress(Progress...)来发布执行的进度。这些进度值被发布到UI线程,并在onProgressUpdate(Progress...)中被接收。
3)onProgressUpdate(Progress...)
执行于UI线程。在publishProgress(Progress...)被调用后立即执行。当后台操作仍旧执行的同时,这个方法用来向用户显示任何形式的进度信息,例如,我们可以用它动态更新进度条或者显示log信息。
4)onPostExecute(Result)
执行于UI线程。后台操作执行完成之后会立即在UI线程执行。后台操作的执行结果会被作为一个参数传递到这个方法中。
4、使用规则
我们在使用这个类的时候必须遵守如下规则:
>Task实例必须在UI线程被创建;
>execute(Params...)必须在UI线程被执行;
>不要手动调用onPreExecute, onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...);
>Task只能执行一次,执行两次会报错;
5、任务的执行顺序
从3.0开始,我们在AsyncTask上执行execute方法之后,多个被执行的Task会被放在队列中顺序执行,避免多任务同时执行带来的错误。
如果你非要多任务的话,可以使用
AsyncTask<Params, Progress, Result> executeOnExecutor (Executor exec, Params... params)这里第一个参数中最常用的是, THREAD_POOL_EXECUTOR 和 SERIAL_EXECUTOR,分别用来实现并行执行和线性执行。你也可以实现自己的Executor来满足更多样的需求。
6、API
构造方法: public AsnycTask()
成员方法:
public final boolean cancel(boolean mayInterruptIfRunning) --> 取消任务的执行
public final boolean isCanceled() --> 返回true,如果任务在正常结束之前被取消
public final AsyncTask<Params, Progress, Result> execute(Params... Params) -->这个方法必须在UI线程执行,并返回它自己,以便调用者能保持它的引用。
public final Result get() --> 获取执行返回的结果
public final Result get(long timeout, TimeUnit unit) -->获取执行返回的结果
public final AsyncTask.Status getStatus() -->获取当前任务的状态