android異步任務詳解 AsynTask


 

android提供了一套專門用於異步處理的類。即:AynsTask類。使用這個類可以為耗時程序開辟一個新線程進行處理,處理完時返回。

其實,AsynTask類就是對Thread類的一個封裝,並且加入了一些新的方法。編程時,兩者都可以實現同樣的功能。本文后面將對AsynTask和Thread進行比較。 

1、AsynTask類結構

asysTask類主要用到的幾個內部回調函數有:

doInBackGround()

onPreExecute()

onPostExecute()

onProgressUpdate()

正是這幾個回調函數構成了AsynTask類的使用邏輯結構。

注意:每個AsynTask子類必須至少復寫doInBackGround()方法。

2、回調邏輯關系

調用關系如下圖:

圖片外鏈:http://p13.freep.cn/p.aspx?u=v20_p13_photo_1301071019339476_0.jpg

1>主線程調用AsynTask子類實例的execute()方法后,首先會調用onPreExecute()方法。onPreExecute()在主線程中運行,可以用來寫一些開始提示代碼。

2>之后啟動新線程,調用doInBackground()方法,進行異步數據處理。

3>處理完畢之后異步線程結束,在主線程中調用onPostExecute()方法。onPostExecute()可以進行一些結束提示處理。

補充:在doInBackground()方法異步處理的時候,如果希望通知主線程一些數據(如:處理進度)。這時,可以調用publishProgress()方法。這時,主線程會調用AsynTask子類的onProgressUpdate()方法進行處理。

3、各個函數間數據的傳遞

通過上面的調用關系,我們就可以大概看出一些數據傳遞關系。如下:

  execute()向doInBackground()傳遞。

  doInBackground()的返回值會傳遞給onPostExecute()。

  publishProgress()向progressUpdate()傳遞。

 

要點:為了調用關系明確及安全,AsynTask類在繼承時要傳入3個泛型。第一個泛型對應execute()向doInBackground()的傳遞類型。第二個泛型對應doInBackground()的返回類型和傳遞給onPostExecute()的類型。第三個泛型對應publishProgress()向progressUpdate()傳遞的類型。

傳遞的數據都是對應類型的數組,數組都是可變長的哦。可以根據具體情況使用。

 

4、實例:

看了上面的內容,應該對asynTask類的使用邏輯有了了解。下面寫一個簡單的例子。

例子功能很簡單:activity中有1個textView和botton。當點擊botton時,異步改變textView的值,並且在相應的回調函數執行時,用System.out.println()輸出值。

布局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width
="fill_parent"
android:layout_height
="fill_parent"
android:orientation
="vertical" >

<TextView
android:id="@+id/text"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
android:text
="@string/hello" />
<Button
android:id="@+id/button"
android:layout_width
="fill_parent"
android:layout_height
="wrap_content"
android:text
="change"
/>

</LinearLayout>


java代碼:

 1 import android.app.Activity;
 2 import android.os.AsyncTask;
 3 import android.os.Bundle;
 4 import android.view.View;
 5 import android.view.View.OnClickListener;
 6 import android.widget.Button;
 7 import android.widget.TextView;
 8 
 9 public class AnsyTestActivity extends Activity {
10     /** Called when the activity is first created. */
11 
12     TextView text = null;
13     Button button = null;
14     String str = null;
15     AnsyTry anys = null;
16     double result = 0;
17 
18     @Override
19     public void onCreate(Bundle savedInstanceState) {
20         super.onCreate(savedInstanceState);
21         setContentView(R.layout.main);
22         text = (TextView) findViewById(R.id.text);
23         button = (Button) findViewById(R.id.button);
24         str = "wei";
25         button.setOnClickListener(new OnClickListener() {
26 
27             @Override
28             public void onClick(View v) {
29                 // TODO Auto-generated method stub
30                 anys = new AnsyTry(text);
31                 anys.execute(str);
32 
33             }
34         });
35     }
36 
37     class AnsyTry extends AsyncTask<String, TextView, Double> {
38 
39         TextView te = null;
40 
41         public AnsyTry(TextView te) {
42             super();
43             this.te = te;
44         }
45 
46         @Override
47         protected Double doInBackground(String... params) {
48             // TODO Auto-generated method stub
49             double dou = 0;
50             if (params[0].equals("wei")) {
51                 System.out.println(Thread.currentThread().getName()
52                         + "  recive wei");
53                 dou = 100;
54             }
55             publishProgress(te);
56             return dou;
57         }
58 
59         @Override
60         protected void onPostExecute(Double result) {
61             // TODO Auto-generated method stub
62             super.onPostExecute(result);
63             System.out.println("postExecute---double---" + result);
64         }
65 
66         @Override
67         protected void onPreExecute() {
68             // TODO Auto-generated method stub\
69             System.out.println("pretExecute------");
70             super.onPreExecute();
71         }
72 
73         @Override
74         protected void onProgressUpdate(TextView... values) {
75             // TODO Auto-generated method stub
76             values[0].setText(values[0].getText() + "1");
77             super.onProgressUpdate(values);
78         }
79 
80     }
81 }

5、總結

初次看到這個異步調用關系可能覺得很復雜,但其實熟悉了之后會發現這種結構很好用。這種結構將所有的線程通信都封裝成回調函數,調用邏輯容易書寫。尤其是在異步處理結束之后,有回調函數進行收尾處理。如果是使用Thread的run()方法,run()結束之后沒有返回值。所以必須要自己建立通信機制。但是,其實使用Handler+Thread機制其實完全可以替代AsynTask的這種調用機制。只要將Handler對象傳給Thread,就可以進行方便的異步處理。且這種MVC模式結構更加明顯,方便管理。所以我覺得,使用asynTask還是Handler+Thread結構,個人喜好吧。但是有一點可以明顯能感覺到得是,Handler+Thread適合進行大框架的異步處理,而asynTask適用於小型簡單的異步處理。以上都是個人觀點+理解。有新觀點請指出。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM