生活随笔
收集整理的這篇文章主要介紹了
AsyncTask应用解析
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
當?shù)谝淮螁右粋€Android程序時,Android會自動創(chuàng)建一個稱為“main”主線程的線程。這個主線程(也稱為UI線程)很重要,因為它負責把事件分派到相應的控件,其中就包括屏幕繪圖事件,它同樣是用戶與Andriod控件交互的線程。比如,當你在屏幕上按下一個按鈕后,UI線程會把這個事件分發(fā)給剛按得那個按鈕,緊接著按鈕設(shè)置它自身為被按下狀態(tài)并向事件隊列發(fā)送一個無效(invalidate)請求。UI線程會把這個請求移出事件隊列并通知按鈕在屏幕上重新繪制自身。
Android單線程模型會在沒有考慮到它的影響的情況下引起Android應用程序性能低下,因為所有的任務都在同一個線程中執(zhí)行,如果執(zhí)行一些耗時的操作,如訪問網(wǎng)絡(luò)或查詢數(shù)據(jù)庫,會阻塞整個用戶界面。當在執(zhí)行一些耗時的操作的時候,不能及時地分發(fā)事件,包括用戶界面重繪事件。從用戶的角度來看,應用程序看上去像掛掉了。更糟糕的是,如果阻塞應用程序的時間過長(現(xiàn)在大概是5秒鐘)Android會向用戶提示一些信息,即打開一個“應用程序沒有相應(application not responding)”的對話框。 在單線程模型中始終要記住兩條法則:
不要阻塞UI線程 確保只在UI線程中訪問Android UI工具包
Android之所以有Handler和AsyncTask,都是為了不阻塞主線程(UI線程),且UI的更新只能在主線程中完成,因此異步處理是不可避免的。
Android 1.5提供了一個工具類:AsyncTask,它使創(chuàng)建需要與用戶界面交互的長時間運行的任務變得更簡單。不需要借助線程和Handler即可實現(xiàn)。
AsyncTask 的優(yōu)勢體現(xiàn)在:
?線程的開銷較大,如果每個任務都要創(chuàng)建一個線程,那么應用程 序的效率要低很多;
?線程無法管理,匿名線程創(chuàng)建并啟動后就不受程序的控制了,如果有很多個請求發(fā)送,那么就會啟動非常多的線程,系統(tǒng)將不堪重負。
?另外,前面已經(jīng)看到,在新線程中更新UI還必須要引入handler,這讓代碼看上去非常臃腫。
AsyncTask定義了三種泛型類型 Params,Progress和Result。
??? ?Params 啟動任務執(zhí)行的輸入?yún)?shù),比如HTTP請求的URL。
??? ?Progress 后臺任務執(zhí)行的百分比。
??? ?Result 后臺執(zhí)行任務最終返回的結(jié)果,比如String。
AsyncTask的執(zhí)行分為四個步驟,每一步都對應一個回調(diào)方法,開發(fā)者需要實現(xiàn)一個或幾個方法。在任務的執(zhí)行過程中,這些方法被自動調(diào)用。
子類化AsyncTask
實現(xiàn)AsyncTask中定義的下面一個或幾個方法
onPreExecute(), 該方法將在執(zhí)行實際的后臺操作前被UI thread調(diào)用。可以在該方法中做一些準備工作,如在界面上顯示一個進度條。 doInBackground(Params...), 將在onPreExecute 方法執(zhí)行后馬上執(zhí)行,該方法運行在后臺線程中。這里將主要負責執(zhí)行那些很耗時的后臺計算工作。可以調(diào)用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現(xiàn)。 onProgressUpdate(Progress...),在publishProgress方法被調(diào)用后,UI thread將調(diào)用這個方法從而在界面上展示任務的進展情況,例如通過一個進度條進行展示。 onPostExecute(Result), 在doInBackground 執(zhí)行完成后,onPostExecute 方法將被UI thread調(diào)用,后臺的計算結(jié)果將通過該方法傳遞到UI thread. 使用AsyncTask類,以下是幾條必須遵守的準則: ??? 1) Task的實例必須在UI thread中創(chuàng)建 ??? 2) execute方法必須在UI thread中調(diào)用 ??? 3) 不要手動的調(diào)用onPreExecute(), onPostExecute(Result),doInBackground(Params...), onProgressUpdate(Progress...)這幾個方法 ??? 4) 該task只能被執(zhí)行一次,否則多次調(diào)用時將會出現(xiàn)異常 從網(wǎng)上獲取一個網(wǎng)頁,在一個TextView中將其源代碼顯示出來
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 > ?{ ? ????????//?可變長的輸入?yún)?shù),與AsyncTask.exucute()對應 ? ?????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)?{ ? ??????????????????????????//?如果知道響應的長度,調(diào)用publishProgress()更新進度 ? ??????????????????????????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頁面的內(nèi)容 ? ????????????message.setText(result); ? ????????????pdialog.dismiss();? ? ????????} ? ? ????????@Override ? ????????protected?void?onPreExecute()?{ ? ????????????//?任務啟動,可以在這里顯示一個對話框,這里簡單處理 ? ????????????message.setText(R.string.task_started); ? ????????} ? ? ????????@Override ? ????????protected?void?onProgressUpdate(Integer...?values)?{ ? ????????????//?更新進度 ? ??????????????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应用解析 的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔 網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔 推薦給好友。