生活随笔
收集整理的這篇文章主要介紹了
AsyncTask应用解析
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
當(dāng)?shù)谝淮螁?dòng)一個(gè)Android程序時(shí),Android會(huì)自動(dòng)創(chuàng)建一個(gè)稱為“main”主線程的線程。這個(gè)主線程(也稱為UI線程)很重要,因?yàn)樗?fù)責(zé)把事件分派到相應(yīng)的控件,其中就包括屏幕繪圖事件,它同樣是用戶與Andriod控件交互的線程。比如,當(dāng)你在屏幕上按下一個(gè)按鈕后,UI線程會(huì)把這個(gè)事件分發(fā)給剛按得那個(gè)按鈕,緊接著按鈕設(shè)置它自身為被按下?tīng)顟B(tài)并向事件隊(duì)列發(fā)送一個(gè)無(wú)效(invalidate)請(qǐng)求。UI線程會(huì)把這個(gè)請(qǐng)求移出事件隊(duì)列并通知按鈕在屏幕上重新繪制自身。
Android單線程模型會(huì)在沒(méi)有考慮到它的影響的情況下引起Android應(yīng)用程序性能低下,因?yàn)樗械娜蝿?wù)都在同一個(gè)線程中執(zhí)行,如果執(zhí)行一些耗時(shí)的操作,如訪問(wèn)網(wǎng)絡(luò)或查詢數(shù)據(jù)庫(kù),會(huì)阻塞整個(gè)用戶界面。當(dāng)在執(zhí)行一些耗時(shí)的操作的時(shí)候,不能及時(shí)地分發(fā)事件,包括用戶界面重繪事件。從用戶的角度來(lái)看,應(yīng)用程序看上去像掛掉了。更糟糕的是,如果阻塞應(yīng)用程序的時(shí)間過(guò)長(zhǎng)(現(xiàn)在大概是5秒鐘)Android會(huì)向用戶提示一些信息,即打開(kāi)一個(gè)“應(yīng)用程序沒(méi)有相應(yīng)(application not responding)”的對(duì)話框。 在單線程模型中始終要記住兩條法則:
不要阻塞UI線程 確保只在UI線程中訪問(wèn)Android UI工具包
Android之所以有Handler和AsyncTask,都是為了不阻塞主線程(UI線程),且UI的更新只能在主線程中完成,因此異步處理是不可避免的。
Android 1.5提供了一個(gè)工具類:AsyncTask,它使創(chuàng)建需要與用戶界面交互的長(zhǎng)時(shí)間運(yùn)行的任務(wù)變得更簡(jiǎn)單。不需要借助線程和Handler即可實(shí)現(xiàn)。
AsyncTask 的優(yōu)勢(shì)體現(xiàn)在:
?線程的開(kāi)銷較大,如果每個(gè)任務(wù)都要?jiǎng)?chuàng)建一個(gè)線程,那么應(yīng)用程 序的效率要低很多;
?線程無(wú)法管理,匿名線程創(chuàng)建并啟動(dòng)后就不受程序的控制了,如果有很多個(gè)請(qǐng)求發(fā)送,那么就會(huì)啟動(dòng)非常多的線程,系統(tǒng)將不堪重負(fù)。
?另外,前面已經(jīng)看到,在新線程中更新UI還必須要引入handler,這讓代碼看上去非常臃腫。
AsyncTask定義了三種泛型類型 Params,Progress和Result。
??? ?Params 啟動(dòng)任務(wù)執(zhí)行的輸入?yún)?shù),比如HTTP請(qǐng)求的URL。
??? ?Progress 后臺(tái)任務(wù)執(zhí)行的百分比。
??? ?Result 后臺(tái)執(zhí)行任務(wù)最終返回的結(jié)果,比如String。
AsyncTask的執(zhí)行分為四個(gè)步驟,每一步都對(duì)應(yīng)一個(gè)回調(diào)方法,開(kāi)發(fā)者需要實(shí)現(xiàn)一個(gè)或幾個(gè)方法。在任務(wù)的執(zhí)行過(guò)程中,這些方法被自動(dòng)調(diào)用。
子類化AsyncTask
實(shí)現(xiàn)AsyncTask中定義的下面一個(gè)或幾個(gè)方法
onPreExecute(), 該方法將在執(zhí)行實(shí)際的后臺(tái)操作前被UI thread調(diào)用??梢栽谠摲椒ㄖ凶鲆恍?zhǔn)備工作,如在界面上顯示一個(gè)進(jìn)度條。 doInBackground(Params...), 將在onPreExecute 方法執(zhí)行后馬上執(zhí)行,該方法運(yùn)行在后臺(tái)線程中。這里將主要負(fù)責(zé)執(zhí)行那些很耗時(shí)的后臺(tái)計(jì)算工作??梢哉{(diào)用 publishProgress方法來(lái)更新實(shí)時(shí)的任務(wù)進(jìn)度。該方法是抽象方法,子類必須實(shí)現(xiàn)。 onProgressUpdate(Progress...),在publishProgress方法被調(diào)用后,UI thread將調(diào)用這個(gè)方法從而在界面上展示任務(wù)的進(jìn)展情況,例如通過(guò)一個(gè)進(jìn)度條進(jìn)行展示。 onPostExecute(Result), 在doInBackground 執(zhí)行完成后,onPostExecute 方法將被UI thread調(diào)用,后臺(tái)的計(jì)算結(jié)果將通過(guò)該方法傳遞到UI thread. 使用AsyncTask類,以下是幾條必須遵守的準(zhǔn)則: ??? 1) Task的實(shí)例必須在UI thread中創(chuàng)建 ??? 2) execute方法必須在UI thread中調(diào)用 ??? 3) 不要手動(dòng)的調(diào)用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個(gè)方法 ??? 4) 該task只能被執(zhí)行一次,否則多次調(diào)用時(shí)將會(huì)出現(xiàn)異常 從網(wǎng)上獲取一個(gè)網(wǎng)頁(yè),在一個(gè)TextView中將其源代碼顯示出來(lái)
package?test.list; ? import?java.io.ByteArrayOutputStream; ? import?java.io.InputStream; ? import?java.util.ArrayList; ? ? import?org.apache.http.HttpEntity; ? import?org.apache.http.HttpResponse; ? import?org.apache.http.client.HttpClient; ? import?org.apache.http.client.methods.HttpGet; ? import?org.apache.http.impl.client.DefaultHttpClient; ? ? import?android.app.Activity; ? import?android.app.ProgressDialog; ? import?android.content.Context; ? import?android.content.DialogInterface; ? import?android.os.AsyncTask; ? import?android.os.Bundle; ? import?android.os.Handler; ? import?android.os.Message; ? import?android.view.View; ? import?android.widget.Button; ? import?android.widget.EditText; ? import?android.widget.TextView; ? ? public?class?NetworkActivity?extends?Activity{ ? ?private?TextView?message; ? ????private?Button?open; ? ????private?EditText?url; ? ? ????@Override ? ????public?void?onCreate(Bundle?savedInstanceState)?{ ? ???????super.onCreate(savedInstanceState); ? ???????setContentView(R.layout.network); ? ??????? message =?(TextView)?findViewById(R.id.message); ? ??????? url =?(EditText)?findViewById(R.id.url); ? ??????? open =?(Button)?findViewById(R.id.open); ? ???????open.setOnClickListener(new?View.OnClickListener()?{ ? ???????????public?void?onClick(View?arg0)?{ ? ??????????????connect(); ? ???????????} ? ???????}); ? ? ????} ? ? ????private?void?connect()?{ ? ?????PageTask? task ?=? new ?PageTask(this); ? ????????task.execute(url.getText().toString()); ? ????} ? ? ? ????class?PageTask?extends?AsyncTask < String ,?Integer,?String > ?{ ? ????????//?可變長(zhǎng)的輸入?yún)?shù),與AsyncTask.exucute()對(duì)應(yīng) ? ?????ProgressDialog?pdialog; ? ????????public?PageTask(Context?context){ ? ????????? pdialog ?=? new ?ProgressDialog(context,?0);??? ? ?????????pdialog.setButton("cancel",?new?DialogInterface.OnClickListener()?{ ? ??????????public?void?onClick(DialogInterface?dialog,?int?i)?{ ? ???????????dialog.cancel(); ? ??????????} ? ?????????}); ? ?????????pdialog.setOnCancelListener(new?DialogInterface.OnCancelListener()?{ ? ??????????public?void?onCancel(DialogInterface?dialog)?{ ? ???????????finish(); ? ??????????} ? ?????????}); ? ?????????pdialog.setCancelable(true); ? ?????????pdialog.setMax(100); ? ?????????pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); ? ?????????pdialog.show(); ? ? ? ????????} ? ????????@Override ? ????????protected?String?doInBackground(String...?params)?{ ? ? ????????????try{ ? ? ???????????????HttpClient? client ?=? new ?DefaultHttpClient(); ? ???????????????//?params[0]代表連接的url ? ???????????????HttpGet? get ?=? new ?HttpGet(params[0]); ? ???????????????HttpResponse? response ?=? client .execute(get); ? ???????????????HttpEntity? entity ?=? response .getEntity(); ? ???????????????long? length ?=? entity .getContentLength(); ? ???????????????InputStream? is ?=? entity .getContent(); ? ???????????????String? s ?=? null ; ? ???????????????if(is?!=?null)?{ ? ???????????????????ByteArrayOutputStream? baos ?=? new ?ByteArrayOutputStream(); ? ? ???????????????????byte[]? buf ?=? new ?byte[128]; ? ? ???????????????????int? ch ?=?-1; ? ? ???????????????????int? count ?=? 0 ; ? ? ???????????????????while(( ch ?=? is .read(buf))?!=?-1)?{ ? ? ??????????????????????baos.write(buf,?0,?ch); ? ? ??????????????????????count?+=?ch; ? ? ??????????????????????if(length? > ?0)?{ ? ??????????????????????????//?如果知道響應(yīng)的長(zhǎng)度,調(diào)用publishProgress()更新進(jìn)度 ? ??????????????????????????publishProgress((int)?((count?/?(float)?length)?*?100)); ? ??????????????????????} ? ? ??????????????????????//?讓線程休眠100ms ? ??????????????????????Thread.sleep(100); ? ???????????????????} ? ??????????????????? s ?=? new ?String(baos.toByteArray());??????????????} ? ???????????????//?返回結(jié)果 ? ???????????????return?s; ? ????????????}?catch(Exception?e)?{ ? ???????????????e.printStackTrace(); ? ? ????????????} ? ? ????????????return?null; ? ? ????????} ? ? ????????@Override ? ????????protected?void?onCancelled()?{ ? ????????????super.onCancelled(); ? ????????} ? ? ????????@Override ? ????????protected?void?onPostExecute(String?result)?{ ? ????????????//?返回HTML頁(yè)面的內(nèi)容 ? ????????????message.setText(result); ? ????????????pdialog.dismiss();? ? ????????} ? ? ????????@Override ? ????????protected?void?onPreExecute()?{ ? ????????????//?任務(wù)啟動(dòng),可以在這里顯示一個(gè)對(duì)話框,這里簡(jiǎn)單處理 ? ????????????message.setText(R.string.task_started); ? ????????} ? ? ????????@Override ? ????????protected?void?onProgressUpdate(Integer...?values)?{ ? ????????????//?更新進(jìn)度 ? ??????????????System.out.println(""+values[0]); ? ??????????????message.setText(""+values[0]); ? ??????????????pdialog.setProgress(values[0]); ? ????????} ? ? ?????} ? ? } ?
轉(zhuǎn)載于:https://www.cnblogs.com/sardine/archive/2011/07/29/2121587.html
總結(jié)
以上是生活随笔 為你收集整理的AsyncTask应用解析 的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
如果覺(jué)得生活随笔 網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔 推薦給好友。