AsyncTask是一个抽象类,我们在使用时需要定义一个它的派生类并重写相关方法。AsyncTask类的声明如下:
public abstract class AsyncTask<Params, Progress, Result>
我们可以看到,AsyncTask是一个泛型类,它的三个类型参数的含义如下:
Params:doInBackground方法的参数类型;
Progress:AsyncTask所执行的后台任务的进度类型;
Result:后台任务的返回结果类型。
我们再来看一下AsyncTask类主要为我们提供了哪些方法:
onPreExecute() //此方法会在后台任务执行前被调用,用于进行一些准备工作
doInBackground(Params… params) //此方法中定义要执行的后台任务,在这个方法中可以调用publishProgress来更新任务进度(publishProgress内部会调用onProgressUpdate方法)
onProgressUpdate(Progress… values) //由publishProgress内部调用,表示任务进度更新
onPostExecute(Result result) //后台任务执行完毕后,此方法会被调用,参数即为后台任务的返回结果
onCancelled() //此方法会在后台任务被取消时被调用
以上方法中,除了doInBackground方法由AsyncTask内部线程池执行外,其余方法均在主线程中执行。
2. AsyncTask的局限性
AsyncTask的优点在于执行完后台任务后可以很方便的更新UI,然而使用它存在着诸多的限制。先抛开内存泄漏问题,使用AsyncTask主要存在以下局限性:
在Android 4.1版本之前,AsyncTask类必须在主线程中加载,这意味着对AsyncTask类的第一次访问必须发生在主线程中;在Android 4.1以及以上版本则不存在这一限制,因为ActivityThread(代表了主线程)的main方法中会自动加载AsyncTask
AsyncTask对象必须在主线程中创建
AsyncTask对象的execute方法必须在主线程中调用
一个AsyncTask对象只能调用一次execute方法
使用例子及说明:
class MyAsyncTask extends AsyncTask<String,Integer,String> {@Overrideprotected void onPreExecute() {super.onPreExecute();Log.i("lgq","sss=s===onPreExecute==");}@Overrideprotected void onCancelled() {//取消该线程方法 myAsyncTask.cancel(false);super.onCancelled();Log.i("lgq","sss=s===onCancelledddd==");}@Overrideprotected void onProgressUpdate(Integer... values) {//进度条回调方法super.onProgressUpdate(values);//通过publishProgress方法传过来的值进行进度条的更新.
// progressBar.setProgress(values[0]);Log.i("lgq","sss=s====="+values[0]);}@Overrideprotected void onPostExecute(String aVoid) {//doInBackground结果回调方法super.onPostExecute(aVoid);Log.i("lgq","........"+aVoid);}@Overrideprotected String doInBackground(String... params) {//参数类型是AsyncTask最后一个参数类型//使用for循环来模拟进度条的进度.for (int i = 0;i < 100; i ++){//调用publishProgress方法将自动触发onProgressUpdate方法来进行进度条的更新.
// ab++;publishProgress(i);//加载进度条方法try {//通过线程休眠模拟耗时操作Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}return params[0];}}
启动AsyncTask
MyAsyncTask myAsyncTask;
myAsyncTask = new MyAsyncTask();
myAsyncTask.execute("ssssw232e3");//这个参数会传递到doInBackground里面
类型后面三个点(String…),是从Java 5开始,Java语言对方法参数支持一种新写法,叫可变长度参数列表
在使用的时候,对于test(String…strings),你可以直接用test()去调用,标示没有参数,也可以用去test(“aaa”),也可以用test(new String[]{“aaa”,”bbb”})。
doInBackground(String... params),onProgressUpdate(Integer... values)参数
都是数组类型