java.lang.Object
↳android.os.AsyncTask<Params, Progress, Result>
概要
AsyncTask可以方便適當地使用UI線程。他允許執行後臺操作並且可以直接在UI線程上發佈結果,而不需要操作線程或handler。
一個異步任務(asynchronous task)由一個後臺運行的計算(computation)來定義,他的結果將在UI線程上發佈。
一個異步任務(asynchronous task)由3個泛化類型(Params,Progress,Result)和4個步驟(begin, doInBackground, processProgress, end)來定義說明。
用法
AsyncTask必須繼承使用。子類至少必須重寫一個方法(doInBackground(Params...))。通常,還會重寫另一個方法(onPostExecute(Result))。
一個子類的例子:
view plaincopy to clipboardprint?
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}
protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}
protected void onPostExecute(Long result) {
showDialog("Downloaded " + result + " bytes");
}
}
創建之後,任務的執行非常簡單:
view plaincopy to clipboardprint?
01.new DownloadFilesTask().execute(url1, url2, url3);
new DownloadFilesTask().execute(url1, url2, url3);
AsyncTask的3個泛化類型
異步任務使用如下3種類型:
1. Params,傳遞給任務的參數類型。
2. Progress,後臺計算執行過程中,進步單位(progress units)的類型。(就是後臺程序已經執行了百分之幾了。)
3. Result, 後臺執行返回的結果的類型。
AsyncTask並不總是需要使用上面的全部3種類型。標識不使用的類型很簡單,只需要使用Void類型即可。
view plaincopy to clipboardprint?
01.private class MyTask extends AsyncTask<Void, Void, Void> { ... }
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
AsyncTask的4個步驟
一個異步任務需要執行下面4個步驟
1. onPreExecute(), 該步驟在任務被執行之後立即由UI線程調用。
這個步驟通常用來建立任務,在用戶接口(UI)上顯示進度條。
2. doInBackground(Params...), 該步驟由後臺線程在onPreExecute()方法執行結束後立即調用。該步驟通常被用來執行耗時的後臺計算。計算的結果必須由該步驟返回,並被傳遞到最後一個步驟中。該步驟也可以使用publishProgress(Progress...)來發佈一個或多個進度單位(units of progress)。這些值將會在onProgressUpdate(Progress...)步驟中被髮布到UI線程。
3. onProgressUpdate(Progress...), 該步驟由UI線程在publishProgress(Progress...)方法調用完後被調用。
並未定義該方法執行的時機。該方法在後臺進程計算仍在執行的時候,在UI上顯示任何形式的進度。一般用於動態地顯示一個進度條或者在文本框中顯示log。
4. onPostExecute(Result), 由UI進程在後臺計算結束後調用。後臺計算的結果會被作爲參數傳遞給這一步驟。
線程規則
爲了能使該類正常執行,需要遵循下列規則:
- Task的實例必須在UI線程中被調用。
- execute(Params...)必須在UI線程中調用。
- 不要手動調用onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)。
- Task只能被執行一次,如果想第二次執行會拋出異常。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/pwair/archive/2010/11/23/6030364.aspx
有一些線程規則必須去遵守,這個類纔會正確的工作:
*任務實例必須創建在 UI線程
* execute(Params...)必須在 UI線程上調用
*不要手動調用 onPreExecute(), onPostExecute(Result), doInBackground(Params...), onProgressUpdate(Progress...)
*任務會執行僅一次(假如有第二個嘗試去執行,將拋出一個異常)
01 |
public
class
Double extends
Activity { |
02 |
|
03 |
public
ProgressBar pBar; |
04 |
|
05 |
/** Called when the activity is first created. */ |
06 |
@Override |
07 |
protected
void
onCreate(Bundle savedInstanceState) { |
08 |
super .onCreate(savedInstanceState);
|
09 |
setContentView(R.layout.main);
|
10 |
pBar = (ProgressBar) findViewById(R.id.progress_bar);
|
11 |
//線程規則二:execute(Params...)必須在UI線程上調用
|
12 |
new
AsyncLoader().execute((Void) null );
|
13 |
}
|
14 |
|
15 |
public
void
initProgress() { |
16 |
pBar.setProgress( 0 );
|
17 |
//這裏可以做一些初始化工作,我就不麻煩寫了,寫幾個變態的for循環算了
|
18 |
for
( int
i = 0 ; i <
100 ; i++) {
|
19 |
System.out.println( "***********"
+ i + "*************" );
|
20 |
}
|
21 |
pBar.setProgress( 30 );
|
22 |
//這裏可以做一些初始化工作,我就不麻煩寫了,寫幾個變態的for循環算了
|
23 |
for
( int
i = 0 ; i <
100 ; i++) {
|
24 |
System.out.println( "***********"
+ i + "*************" );
|
25 |
}
|
26 |
pBar.setProgress( 60 );
|
27 |
//這裏可以做一些初始化工作,我就不麻煩寫了,寫幾個變態的for循環算了
|
28 |
for
( int
i = 0 ; i <
100 ; i++) {
|
29 |
System.out.println( "***********"
+ i + "*************" );
|
30 |
}
|
31 |
pBar.setProgress( 100 );
|
32 |
Intent intent =
new
Intent(Double. this , Double2. class );
|
33 |
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
34 |
startActivity(intent);
|
35 |
finish();
|
36 |
}
|
37 |
|
38 |
//繼承於AsyncTask
|
39 |
class
AsyncLoader extends
AsyncTask<Void, Void, Integer>{ |
40 |
|
41 |
@Override |
42 |
protected
Integer doInBackground(Void... params) { |
43 |
initProgress();
|
44 |
return
null ;
|
45 |
}
|
46 |
|
47 |
}
|
48 |
} |