AsyncTask 學習 (2)

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 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章