Android異步加載AsyncTask的使用
Android系統(tǒng)給我們提供了AsyncTask這樣一個類,來幫助我們快速實現(xiàn)多線程開發(fā),它的底層實現(xiàn),其實就是一個線程池。
AsyncTask,顧名思義就是用來做異步處理的。通過AsyncTask,我們可以非常方便的解決多線程,以及多線程之間的通信問題。
AsyncTask參數(shù)
抽象類AsyncTask具有三個泛型參數(shù):
AsyncTask
Params: 這個泛型指定的是我們傳遞給異步任務(wù)執(zhí)行時的參數(shù)的類型
Progress: 這個泛型指定的是我們的異步任務(wù)在執(zhí)行的時候?qū)?zhí)行的進(jìn)度返回給UI線程的參數(shù)的類型
Result: 這個泛型指定的異步任務(wù)執(zhí)行完后返回給UI線程的結(jié)果的類型
我們在創(chuàng)建AsyncTask的時候,需要指定這三個參數(shù)。
AsyncTask方法
AsyncTask具有這樣幾個抽象方法:
onPreExecute(): 這個方法是在執(zhí)行異步任務(wù)之前的時候執(zhí)行,并且是在UI Thread當(dāng)中執(zhí)行的,通常我們在這個方法里做一些UI控件的初始化的操作,例如彈出ProgressDialog
doInBackground(Params... params): 在onPreExecute()方法執(zhí)行完之后,會馬上執(zhí)行這個方法,這個方法就是來處理異步任務(wù)的方法,
Android操作系統(tǒng)會在后臺的線程池當(dāng)中開啟一個worker thread來執(zhí)行我們的這個方法,所以這個方法是在worker thread當(dāng)中執(zhí)行的,這個方法執(zhí)行完之后就可以將我們的執(zhí)行結(jié)果發(fā)送給我們的最后一個 onPostExecute 方法,因此,doInBackground是這四個方法中唯一必須要重寫的方法,在這個方法中,我們可以從網(wǎng)絡(luò)當(dāng)中獲取數(shù)據(jù)等一些耗時操作
onProgressUpdate(Progess... values): 這個方法也是在UI Thread當(dāng)中執(zhí)行的,我們在異步任務(wù)執(zhí)行的時候,
有時候需要將執(zhí)行的進(jìn)度返回給我們的UI界面,例如下載一張網(wǎng)絡(luò)圖片,我們需要時刻顯示其下載的進(jìn)度,
就可以使用這個方法來更新我們的進(jìn)度。這個方法在調(diào)用之前,我們需要在 doInBackground 方法中
調(diào)用一個 publishProgress(Progress) 的方法來將我們的進(jìn)度時時刻刻傳遞給 onProgressUpdate 方法從而來更新進(jìn)度
onPostExecute(Result... result): 當(dāng)我們的異步任務(wù)執(zhí)行完之后,就會將結(jié)果返回給這個方法,這個方法也是在UI Thread當(dāng)中調(diào)用的,
我們可以將返回的結(jié)果顯示在UI控件上
AsyncTask使用
現(xiàn)在回到我們的例子中,我們利用AsyncTask來下載圖像,當(dāng)然,下載圖像的方法還是使用那個getBitmapFromUrl()方法。首先,我們先寫一個ASyncDownloadImage類,繼承AsyncTask:
private class ASyncDownloadImage extends AsyncTask {
private ImageView imageView;
private String url;
public ASyncDownloadImage(ImageView imageView, String url) {
this.imageView = imageView;
this.url = url;
}
@Override
protected Bitmap doInBackground(String... params) {
return getBitmapFromUrl(params[0]);
}
@Override
protected void onPostExecute(Bitmap bitmap) {
super.onPostExecute(bitmap);
if (imageView.getTag().equals(url)) {
imageView.setImageBitmap(bitmap);
}
}
}
這個AsyncTask我們重寫了doInBackground用來異步下載圖像,重寫了onPostExecute來將圖像設(shè)置到ImageView上。因此,我們將AsyncTask的三個泛型參數(shù)設(shè)置為:
AsyncTask
即參數(shù)類型為String——url,進(jìn)度類型——Void 不需要,返回類型——Bitmap 下載的圖像。在設(shè)置圖像的時候,我們同樣需要通過tag來進(jìn)行判斷。
最后,我們與使用多線程一樣,創(chuàng)建一個showImageByASync方法,來調(diào)用AsyncTask:
/**
* Using ASyncTask
* @param imageView
* @param url
*/
public void showImageByASync(ImageView imageView, String url) {
ASyncDownloadImage task = new ASyncDownloadImage(imageView, url);
task.execute(url);
}
AsyncTask中有幾個地方還是需要注意下的:
execute方法只能在UI線程中調(diào)用
AsyncTask實例也必須在UI線程中創(chuàng)建
AsyncTask的抽象方法不要手動去調(diào)用,系統(tǒng)自動會去管理
AsyncTask只能執(zhí)行一次
最后,只需要將Adapter中的getView方法的mImageLoader.showImageByThread(viewHolder.imageView, url);改為如下所示即可:
mImageLoader.showImageByASync(viewHolder.imageView, url);





