在新线程中更新UI还必须要引入handler,这让代码看上去非常臃肿。
为了解决这一问题,Android在1.5版本引入了android.os.AsyncTask。AsyncTask的特点是任务在主线程之外运行,而回调方法是在主线程中执行,这就有效地避免了使用Handler带来的麻烦。AsyncTask的任务其实最后是在AsyncTask本身的一个静态线程池变量中被执行的。当然因为线程池变量为静态的,所以所有的AsyncTask实例的任务其实是在同一个线程池中被执行的。AsyncTask类本身有一个静态的Handler.
为了解决这一问题,Android在1.5版本引入了android.os.AsyncTask。AsyncTask的特点是任务在主线程之外运行,而回调方法是在主线程中执行,这就有效地避免了使用Handler带来的麻烦。AsyncTask的任务其实最后是在AsyncTask本身的一个静态线程池变量中被执行的。当然因为线程池变量为静态的,所以所有的AsyncTask实例的任务其实是在同一个线程池中被执行的。AsyncTask类本身有一个静态的Handler.
该Handler用无参数的构造函数进行实例化。与UI进行交互的AsyncTask的函数接口cancel(),onProgressUpdate(),onPostExecute()最终也是在该Handler上进行调用。为了确保UI的线程安全,该Handler必须在UI线程上。因此AsyncTask类必须在UI线程上被载入。当然为了安全AsyncTask必须在UI线程上被实例。
publicabstractclass
AsyncTask
extendsObject
java.lang.Object
android.os.AsyncTask<Params,Progress,Result>
第一个为doInBackground接受的参数,第二个为显示进度的参数,第三个为doInBackground返回和onPostExecute传入的参数。
AsyncTaskmustbesubclassedtobeused.Thesubclasswilloverrideatleastonemethod(doInBackground(Params...)),andmostoftenwilloverrideasecondone(onPostExecute(Result).)
Hereisanexampleofsubclassing:
privateclassDownloadFilesTaskextendsAsyncTask<URL,Integer,Long>{
protectedLongdoInBackground(URL...urls){
intcount=urls.length;
longtotalSize=0;
for(inti=0;i<count;i++){
totalSize+=Downloader.downloadFile(urls<wbr style="line-height:22px">);<br style="line-height:22px"> publishProgress(</wbr>(int)((i/(float)count)*100));
}
returntotalSize;
}
protectedvoidonProgressUpdate(Integer...progress){
setProgressPercent(progress[0]);
}
protectedvoidonPostExecute(Longresult){//这个是doInBackground执行完后调用
showDialog("Downloaded"+result+"bytes");
}
}
Oncecreated,ataskisexecutedverysimply:
newDownloadFilesTask().execute(url1,url2,url3);
AsyncTask'sgenerictypes
Thethreetypesusedbyanasynchronoustaskarethefollowing:
1.Params,thetypeoftheparameterssenttothetaskuponexecution.
2.Progress,thetypeoftheprogressunitspublishedduringthebackgroundcomputation.
3.Result,thetypeoftheresultofthebackgroundcomputation.
Notalltypesarealwaysusedbyanasynchronoustask.Tomarkatypeasunused,simplyusethetypeVoid:
privateclassMyTaskextendsAsyncTask<Void,Void,Void>{...}
Thereareafewthreadingrulesthatmustbefollowedforthisclasstoworkproperly:
*ThetaskinstancemustbecreatedontheUIthread.【只能在UI线程中实例化】
*execute(Params...)mustbeinvokedontheUIthread.【只能在UI线程中调用execute】why?
*DonotcallonPreExecute(),onPostExecute(Result),doInBackground(Params...),onProgressUpdate(Progress...)manually.
*Thetaskcanbeexecutedonlyonce(anexceptionwillbethrownifasecondexecutionisattempted.)【只能执行一次,第二次回有问题】
AsyncTask
extendsObject
java.lang.Object
android.os.AsyncTask<Params,Progress,Result>
第一个为doInBackground接受的参数,第二个为显示进度的参数,第三个为doInBackground返回和onPostExecute传入的参数。
AsyncTaskmustbesubclassedtobeused.Thesubclasswilloverrideatleastonemethod(doInBackground(Params...)),andmostoftenwilloverrideasecondone(onPostExecute(Result).)
Hereisanexampleofsubclassing:
privateclassDownloadFilesTaskextendsAsyncTask<URL,Integer,Long>{
protectedLongdoInBackground(URL...urls){
intcount=urls.length;
longtotalSize=0;
for(inti=0;i<count;i++){
totalSize+=Downloader.downloadFile(urls<wbr style="line-height:22px">);<br style="line-height:22px"> publishProgress(</wbr>(int)((i/(float)count)*100));
}
returntotalSize;
}
protectedvoidonProgressUpdate(Integer...progress){
setProgressPercent(progress[0]);
}
protectedvoidonPostExecute(Longresult){//这个是doInBackground执行完后调用
showDialog("Downloaded"+result+"bytes");
}
}
Oncecreated,ataskisexecutedverysimply:
newDownloadFilesTask().execute(url1,url2,url3);
AsyncTask'sgenerictypes
Thethreetypesusedbyanasynchronoustaskarethefollowing:
1.Params,thetypeoftheparameterssenttothetaskuponexecution.
2.Progress,thetypeoftheprogressunitspublishedduringthebackgroundcomputation.
3.Result,thetypeoftheresultofthebackgroundcomputation.
Notalltypesarealwaysusedbyanasynchronoustask.Tomarkatypeasunused,simplyusethetypeVoid:
privateclassMyTaskextendsAsyncTask<Void,Void,Void>{...}
Thereareafewthreadingrulesthatmustbefollowedforthisclasstoworkproperly:
*ThetaskinstancemustbecreatedontheUIthread.【只能在UI线程中实例化】
*execute(Params...)mustbeinvokedontheUIthread.【只能在UI线程中调用execute】why?
*DonotcallonPreExecute(),onPostExecute(Result),doInBackground(Params...),onProgressUpdate(Progress...)manually.
*Thetaskcanbeexecutedonlyonce(anexceptionwillbethrownifasecondexecutionisattempted.)【只能执行一次,第二次回有问题】