Android 異步任務AsyncTask
時間:2018-09-26 來(lai)源:未知
在(zai)日(ri)常(chang)的(de)(de)開(kai)發(fa)(fa)過程(cheng)(cheng)(cheng)(cheng)中(zhong),Android UI操(cao)作并(bing)不是(shi)線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)安全的(de)(de)并(bing)且這些操(cao)作必須(xu)在(zai)UI線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)中(zhong)執(zhi)行,當一(yi)個程(cheng)(cheng)(cheng)(cheng)序第一(yi)次啟(qi)(qi)動時,Android會(hui)同(tong)時啟(qi)(qi)動一(yi)個對(dui)(dui)(dui)應的(de)(de)主(zhu)(zhu)線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)(Main Thread),主(zhu)(zhu)線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)主(zhu)(zhu)要(yao)負責處(chu)理與UI相關的(de)(de)事(shi)件(jian)(jian)(jian),如(ru)(ru):用戶的(de)(de)按(an)鍵事(shi)件(jian)(jian)(jian),用戶接觸(chu)屏幕(mu)的(de)(de)事(shi)件(jian)(jian)(jian)以及(ji)屏幕(mu)繪(hui)圖(tu)(tu)事(shi)件(jian)(jian)(jian),并(bing)把(ba)相關的(de)(de)事(shi)件(jian)(jian)(jian)分(fen)發(fa)(fa)到對(dui)(dui)(dui)應的(de)(de)組件(jian)(jian)(jian)進(jin)行處(chu)理,如(ru)(ru)果(guo)在(zai)非UI線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)中(zhong)直接操(cao)作UI線(xian)(xian)程(cheng)(cheng)(cheng)(cheng),會(hui)拋出android.view.ViewRoot$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views,由于UI線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)負責事(shi)件(jian)(jian)(jian)的(de)(de)監(jian)聽(ting)和(he)繪(hui)圖(tu)(tu),因(yin)此,必須(xu)保證UI線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)能夠隨時響應用戶的(de)(de)需(xu)求,UI線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)里的(de)(de)操(cao)作應該向中(zhong)斷(duan)事(shi)件(jian)(jian)(jian)那樣短小(xiao),費時的(de)(de)操(cao)作(如(ru)(ru)網絡連接)需(xu)要(yao)另開(kai)線(xian)(xian)程(cheng)(cheng)(cheng)(cheng),否(fou)則,如(ru)(ru)果(guo)UI線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)超過5s沒有(you)響應用戶請(qing)求,會(hui)彈出對(dui)(dui)(dui)話框提醒用戶終止應用程(cheng)(cheng)(cheng)(cheng)序。如(ru)(ru)果(guo)在(zai)新開(kai)的(de)(de)線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)中(zhong)需(xu)要(yao)對(dui)(dui)(dui)UI進(jin)行設定,就可能違反(fan)單線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)模(mo)(mo)型,常(chang)常(chang)會(hui)通(tong)過異步(bu)任務AsyncTask的(de)(de)方式來維護單線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)模(mo)(mo)型。AsyncTask對(dui)(dui)(dui)線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)間的(de)(de)通(tong)訊做了包裝,是(shi)后(hou)臺線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)和(he)UI線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)可以簡(jian)易通(tong)訊:后(hou)臺線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)執(zhi)行異步(bu)任務,將結果(guo)告知Android UI線(xian)(xian)程(cheng)(cheng)(cheng)(cheng)。我(wo)們(men)需(xu)要(yao)在(zai)耗時間的(de)(de)地方使用自定義的(de)(de)AsyncTask。
首先,繼承AsyncTask
參數說明如下:
Params標示輸入參數。
Progress標(biao)示子(zi)線程執行的百分比。
Result標示返回值(zhi)類型。
根據需求(qiu)實現如下方(fang)法:
onPreExecute()方法。
doInBackground(Params... params)方法。
publishProgress(Params... params)方法。
onProgressUpdate(Params... values)方(fang)法。
onPostExecute(Params... params)方法(fa)。
通過(guo)excute(Params... params)執(zhi)行異(yi)步任務。其次(ci),要注意AsyncTask要在Android 的UI線程(cheng)創建,異(yi)步任務的execute()方(fang)(fang)法(fa)必(bi)須在Android的UI 線程(cheng)中調(diao)用,且異(yi)步任務只能被執(zhi)行一次(ci),不需要手動調(diao)用onPreExecute(), onPostExecute(),doInBackground() onProgressUpdate()方(fang)(fang)法(fa)。
實例代碼:
AsyncTask子類LoadPicAsyncTask完成網絡(luo)數(shu)據下載功能:
創建LoadPicAsyncTask對象(xiang):
LoadPicAsyncTask p = new LoadPicAsyncTask(ImageView控件對象);
執行LoadPicAsyncTask異步(bu)任務:
p.execute(網絡(luo)資源url資源定位符);
實現LoadPicAsyncTask內部(bu)類:
class LoadPicAsyncTask extends AsyncTask
//輔助控件引用變(bian)量
public ImageView mImageView;
public Bitmap bitmap;
//實現異步任務LoadPicAsyncTask構造器:
public LoadPicAsyncTask(ImageView imageView) {
mImageView = imageView;
}
//實(shi)現異步(bu)任務的doInBackground()方法(fa),形(xing)參列表(biao)是String類型
protected Void doInBackground(String... arg0) {
try {
//獲得形參內容:
String url = arg0[0];
//創建網絡Http訪問客戶端:
HttpClient client = new DefaultHttpClient();
//創建Post請求(qiu)對(dui)象(xiang)
HttpPost post = new HttpPost(url);
//客戶端發(fa)送Post網絡請求
HttpResponse response = client.execute(post);
//獲(huo)得(de)服(fu)務器的返回值(zhi)
if (response.getStatusLine().getStatusCode() == 200) {
//獲得(de)網絡數據實體:
HttpEntity entity = response.getEntity();
//獲得網絡(luo)數(shu)據的輸(shu)入流(liu)對象
InputStream is = entity.getContent();
//讀取(qu)網(wang)絡數據流內容獲得Bitmap對象
bitmap = BitmapFactory.decodeStream(is);
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
//實現異步任(ren)務的onPostExecute方法:
protected void onPostExecute(Void result) {
// TODO 自動生(sheng)成(cheng)的方法(fa)存根(gen)
super.onPostExecute(result);
//顯(xian)示網(wang)絡下載的內(nei)容(rong):
mImageView.setImageBitmap(bitmap);
}
}
}