關(guān)于AsyncTask的解釋米愿,Google上面是這樣說的:
AsyncTask enables proper and easy use of the UI thread. This class allows you to perform background operations and publish results on the UI thread without having to manipulate threads and/or handlers.
An asynchronous task is defined by a computation that runs on a background thread and whose result is published on the UI thread. An asynchronous task is defined by 3 generic types, called Params, Progress and Result, and 4 steps, called onPreExecute, doInBackground, onProgressUpdate and onPostExecute.
大概意思就是說“它使創(chuàng)建異步任務(wù)變得更加簡單,不再需要編寫任務(wù)線程和Handler實例即可完成相同的任務(wù)鼻吮。一個異步任務(wù)通常是在后臺運行的計算等然后將結(jié)果發(fā)送到UI主線程中去育苟。通常情況下,異步任務(wù)被定義為3種通用類型椎木,分別為:參數(shù)违柏、過程以及結(jié)果和4個步驟,分別為“onPreExecute香椎、doInBackground漱竖、onProgressUpdate、onPostExecute””這就是關(guān)于異步任務(wù)的大概說明畜伐。
怎么來理解AsyncTask呢闲孤?通俗一點來說,AsyncTask就相當(dāng)于Android給我們提供了一個多線程編程的一個框架烤礁,其介于Thread和Handler之間,我們?nèi)绻x一個AsyncTask肥照,就需要定義一個類來繼承AsyncTask這個抽象類脚仔,并實現(xiàn)其唯一的一個 doInBackgroud 抽象方法。要掌握AsyncTask舆绎,我們就必須要一個概念鲤脏,總結(jié)起來就是: 3個泛型,4個步驟吕朵。
3個泛型
3個泛型指的是什么呢猎醇?我們來看看AsyncTask這個抽象類的定義,當(dāng)我們定義一個類來繼承AsyncTask這個類的時候努溃,我們需要為其指定3個泛型參數(shù):
public abstractclassAsyncTask
Params:這個泛型指定的是我們傳遞給異步任務(wù)執(zhí)行時的參數(shù)的類型
Progress:這個泛型指定的是我們的異步任務(wù)在執(zhí)行的時候?qū)?zhí)行的進度返回給UI線程的參數(shù)的類型
Result:這個泛型指定的異步任務(wù)執(zhí)行完后返回給UI線程的結(jié)果的類型
4個步驟
4個步驟:當(dāng)我們執(zhí)行一個異步任務(wù)的時候硫嘶,其需要按照下面的4個步驟分別執(zhí)行:
1、onPreExecute():
這個方法是在執(zhí)行異步任務(wù)之前的時候執(zhí)行梧税,并且是在UI Thread當(dāng)中執(zhí)行的沦疾,通常我們在這個方法里做一些UI控件的初始化的操作称近,例如彈出要給ProgressDialog。
2哮塞、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 方法家凯,在這個方法里缓醋,我們可以從網(wǎng)絡(luò)當(dāng)中獲取數(shù)據(jù)等一些耗時的操作。
3肆饶、onProgressUpdate(Progess... values):
這個方法也是在UI Thread當(dāng)中執(zhí)行的改衩,我們在異步任務(wù)執(zhí)行的時候,有時候需要將執(zhí)行的進度返回給我們的UI界面驯镊,例如下載一張網(wǎng)絡(luò)圖片葫督,我們需要時刻顯示其下載的進度,就可以使用這個方法來更新我們的進度板惑。這個方法在調(diào)用之前橄镜,我們需要在 doInBackground 方法中調(diào)用一個 publishProgress(Progress) 的方法來將我們的進度時時刻刻傳遞給 onProgressUpdate 方法來更新。
4冯乘、onPostExecute(Result... result):
當(dāng)我們的異步任務(wù)執(zhí)行完之后洽胶,就會將結(jié)果返回給這個方法,這個方法也是在UI Thread當(dāng)中調(diào)用的裆馒,我們可以將返回的結(jié)果顯示在UI控件上姊氓。
為什么我們的AsyncTask抽象類只有一個 doInBackground 的抽象方法呢?喷好?原因是翔横,我們?nèi)绻鲆粋€異步任務(wù),我們必須要為其開辟一個新的Thread梗搅,讓其完成一些操作禾唁,而在完成這個異步任務(wù)時,我可能并不需要彈出要給ProgressDialog无切,我并不需要隨時更新我的ProgressDialog的進度條荡短,我也并不需要將結(jié)果更新給我們的UI界面,所以除了 doInBackground 方法之外的三個方法哆键,都不是必須有的掘托,因此我們必須要實現(xiàn)的方法是 doInBackground 方法。
**簡單使用**
//進度框顯示progressDialog =newProgressDialog(MainActivity.this);
progressDialog.setTitle("提示信息");
progressDialog.setMessage("正在下載中籍嘹,請稍后......");//? ? 設(shè)置setCancelable(false); 表示我們不能取消這個彈出框烫映,等下載完成之后再讓彈出框消失progressDialog.setCancelable(false);//? ? 設(shè)置ProgressDialog樣式為水平的樣式progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);//下載類publicclassMyAsyncTaskextendsAsyncTask{
@Override
protectedvoidonPreExecute() {super.onPreExecute();//? ? 在onPreExecute()中我們讓ProgressDialog顯示出來progressDialog.show();
}
@Override
protected Bitmap doInBackground(String... params) {
Bitmap bitmap =null;try{
URL url =newURL(params[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setConnectTimeout(5*1000);
conn.setRequestMethod("GET");
InputStream inputStream = conn.getInputStream();if(conn.getResponseCode() == HttpURLConnection.HTTP_OK) {
int fileLength = conn.getContentLength();
ByteArrayOutputStream outStread =newByteArrayOutputStream();
byte[] buffer =newbyte[1024];
int length =0;
long total =0;while((length = inputStream.read(buffer)) !=-1) {
outStread.write(buffer,0, length);
total += length;if(fileLength >0) {
publishProgress((int) (total *100/ fileLength));
}
}
outStread.close();
inputStream.close();
byte[] data = outStread.toByteArray();if(data !=null) {
bitmap = BitmapFactory.decodeByteArray(data,0, data.length);
}else{
Toast.makeText(MainActivity.this,"Image error!", Toast.LENGTH_LONG).show();
}returnbitmap;
}
}catch(Exception e) {
e.printStackTrace();
}returnnull;
}
@Override
protectedvoidonProgressUpdate(Integer... values) {super.onProgressUpdate(values);//? ? 更新ProgressDialog的進度條progressDialog.setProgress(values[0]);
}
@Override
protectedvoidonPostExecute(Bitmap bitmap) {super.onPostExecute(bitmap);
imageView.setImageBitmap(bitmap);try{
saveFile(bitmap,"netpic.jpg");
}catch(IOException e) {
e.printStackTrace();
}
progressDialog.dismiss();
}
}//在UI主線程中執(zhí)行下載程序StringpicUrl ="http://img3.imgtn.bdimg.com/it/u=2437337628,1430863508&fm=214&gp=0.jpg";newMyAsyncTask().execute(picUrl);