AsyncTask實現(xiàn)的原理,和適用的優(yōu)缺點 AsyncTask,是android提供的輕量級的異步類,可以直接繼承AsyncTask,在類中實現(xiàn)異步操作,并提供接口反饋當(dāng)前異步執(zhí)行的程度(可以通過接口實現(xiàn)UI進(jìn)度更新),最后反饋執(zhí)行的結(jié)果給UI主線程. 使用的優(yōu)點: 簡單,快捷 過程可控 使用的缺點: 在使用多個異步操作和并需要進(jìn)行Ui變更時,就變得復(fù)雜起來. 2 Handler異步實現(xiàn)的原理和適用的優(yōu)缺點 在Handler 異步實現(xiàn)時,涉及到 Handler, Looper, Message,Thread四個對象,內(nèi)存不足實現(xiàn)異步的流程是主線程啟動Thread(子線程)àthread(子線程)運行并生成Message-àLooper獲取Message并傳遞給HandleràHandler逐個獲取Looper中的Message,并進(jìn)行UI變更。 使用的優(yōu)點: 結(jié)構(gòu)清晰,功能定義明確 對于多個后臺任務(wù)時,簡單,清晰 --------------------------------------------------------------------------------------------- AsyncTask與Handler的相同點跟區(qū)別 問題1:有人說異步任務(wù)比Handler輕量級,對嗎? 答: 通過看源碼,發(fā)現(xiàn)AsyncTask實際上就是一個線程池,而網(wǎng)上的說法是AsyncTask比handler要輕量級,顯然上不準(zhǔn)確的,只能這樣說,AsyncTask在代碼上比handler要輕量級別,而實際上要比handler更耗資源,因為AsyncTask底層是一個線程池!而Handler僅僅就是發(fā)送了一個消息隊列,連線程都沒有開。 但是,如果異步任務(wù)的數(shù)據(jù)特別龐大,AsyncTask這種線程池結(jié)構(gòu)的優(yōu)勢就體現(xiàn)出來了。 AsyscTask定義了三種泛型類型params,progress和result. 1, params啟動任務(wù)執(zhí)行的輸入?yún)?shù),比如http請求的URL 2, progress后臺任務(wù)執(zhí)行的百分比 3, result后臺執(zhí)行任務(wù)最終返回的結(jié)果,比如String,比如我需要得到的list AsyncTask方法: 必選方法: 1, doinbackground(params…) 后臺執(zhí)行,比較耗時的操作都可以放在這里。 注意這里不能直接操作UI。此方法在后臺線程執(zhí)行,完成任務(wù)的主要工作 ,通常需要較長的時間。在執(zhí)行過程中可以調(diào)用 Public progress(progress…)來更新任務(wù)的進(jìn)度。 2, onpostexecute(result)相當(dāng)于handler處理UI的方式,在這里可以使用在 doinbackground得到的結(jié)果處理操作UI。此方法在主線程執(zhí)行,任務(wù)執(zhí)行的結(jié)果作為此方法的參數(shù)返回。 可選方法: 1, onprogressupdate(progress…) 可以使用進(jìn)度條增加用戶體驗度。此方法在主線程執(zhí)行,用戶顯示任務(wù)執(zhí)行的進(jìn)度。 2, onpreExecute() 這里是最新用戶調(diào)用excute時的接口,當(dāng)任務(wù)執(zhí)行之前開始調(diào)用此方法,可以在這里顯示進(jìn)度對話框。 3, onCancelled() 用戶調(diào)用取消時,要做的操作 AsyncTask三個狀態(tài):pending,running,finished 使用AsyncTask類,遵守的準(zhǔn)則: 1, Task的實例必須在UI thread中創(chuàng)建; 2, Execute方法必須在UI thread中調(diào)用 3, 不要手動的調(diào)用onPfreexecute(),onPostExecute(result) Doinbackground(params…),onProgressupdate(progress…)這幾個方法; 4, 該task只能被執(zhí)行一次,否則多次調(diào)用時將會出現(xiàn)異常; AsyncTask的整個調(diào)用過程都是從execute方法開始的,一旦在主線程中調(diào)用execute方法,就可以通過onpreExecute方法,這是一個預(yù)處理方法,比如可以在這里開始一個進(jìn)度框,同樣也可以通過onprogressupdate方法給用戶一個進(jìn)度條的顯示,增加用戶體驗;最后通過onpostexecute方法,相當(dāng)于handler處理UI的方式,在這里可以使用在 doinbackground得到的結(jié)果處理操作UI。此方法在主線程執(zhí)行,任務(wù)執(zhí)行的結(jié)果作為此方法的參數(shù)返回。 關(guān)于AsyncTask和Handler+Thread的一點破事 其實都是和線程操作有關(guān)的東西 thread的run()殘缺返回值于是+handler組合就可以做出時候用戶體驗的界面+線程運作了 而asyn直接實現(xiàn)就可以了 class InitTask extends AsyncTask<Integer, Integer, String>{ //后面尖括號內(nèi)分別是參數(shù)(例子里是線程休息時間),進(jìn)度(publishProgress用到),返回值 類型 @Override protected void onPreExecute() { //第一個執(zhí)行方法 pdialog.show(); super.onPreExecute(); } @Override protected String doInBackground(Integer... params) { //第二個執(zhí)行方法,onPreExecute()執(zhí)行完后執(zhí)行 initoken(); return "初始化完畢,請繼續(xù)操作!"; } @Override protected void onProgressUpdate(Integer... progress) { //這個函數(shù)在doInBackground調(diào)用publishProgress時觸發(fā),雖然調(diào)用時只有一個參數(shù) //但是這里取到的是一個數(shù)組,所以要用progesss[0]來取值 //第n個參數(shù)就用progress[n]來取值 // if (progress[0] == 100)setTitle(R.string.app_name); super.onProgressUpdate(progress); } @Override protected void onPostExecute(String result) { //doInBackground返回時觸發(fā),換句話說,就是doInBackground執(zhí)行完后觸發(fā) //這里的result就是上面doInBackground執(zhí)行后的返回值,所以這里是"執(zhí)行完畢" pdialog.dismiss(); setTitle(result); super.onPostExecute(result); } } 這個的功能就是在線程運行時候顯示progressdialog,線程結(jié)束dialog消失 效果和http://hi.baidu.com/snk4/blog/item/b08ac13f2b92f7f355e7232c.html一樣 不過需要注意的是,asyn結(jié)構(gòu)比較"整齊" thread+handler比較靈活. AsyncTask對比Thread加Handler 很多網(wǎng)友可能發(fā)現(xiàn)Android平臺很多應(yīng)用使用的都是AsyncTask,而并非Thread和Handler去更新UI,這里Android123給大家說下他們到底有什么區(qū)別,我們平時應(yīng)該使用哪種解決方案。從Android 1.5開始系統(tǒng)將AsyncTask引入到android.os包中,過去在很早1.1和1.0 SDK時其實官方將其命名為UserTask,其內(nèi)部是JDK 1.5開始新增的concurrent庫,做過J2EE的網(wǎng)友可能明白并發(fā)庫效率和強(qiáng)大性,比Java原始的Thread更靈活和強(qiáng)大,但對于輕量級的使用更為占用系統(tǒng)資源。Thread是Java早期為實現(xiàn)多線程而設(shè)計的,比較簡單不支持concurrent中很多特性在同步和線程池類中需要自己去實現(xiàn)很多的東西,對于分布式應(yīng)用來說更需要自己寫調(diào)度代碼,而為了Android UI的刷新Google引入了Handler和Looper機(jī)制,它們均基于消息實現(xiàn),有事可能消息隊列阻塞或其他原因無法準(zhǔn)確的使用。 推薦大家使用AsyncTask代替Thread+Handler的方式,不僅調(diào)用上更為簡單,經(jīng)過實測更可靠一些,Google在Browser中大量使用了異步任務(wù)作為處理耗時的I/O操作,比如下載文件、讀寫數(shù)據(jù)庫等等,它們在本質(zhì)上都離不開消息,但是AsyncTask相比Thread加Handler更為可靠,更易于維護(hù),但AsyncTask缺點也是有的比如一旦線程開啟即dobackground方法執(zhí)行后無法給線程發(fā)送消息,僅能通過預(yù)先設(shè)置好的標(biāo)記來控制邏輯,當(dāng)然可以通過線程的掛起等待標(biāo)志位的改變來通訊,對于某些應(yīng)用Thread和Handler以及Looper可能更靈活。 |
|