Android——AsyncTask

android提供了一套專門用於異步處理的類。即:AynsTask類。使用這個類可以爲耗時程序開闢一個新線程進行處理,處理完時返回。其實,AsynTask類就是對Thread類的一個封裝,並且加入了一些新的方法。編程時,兩者都可以實現同樣的功能。本文後面將對AsynTask和Thread進行比較。

1、AsynTask類結構
asysTask類主要用到的幾個內部回調函數有:
doInBackGround()

onPreExecute()

onPostExecute()

onProgressUpdate()
複製代碼
正是這幾個回調函數構成了AsynTask類的使用邏輯結構。
注意:每個AsynTask子類必須至少複寫doInBackGround()方法。
2、回調邏輯關係
調用關係如下圖:
    

 


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代碼:
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class AnsyTestActivity extends Activity {
    /** Called when the activity is first created. */
   
    TextView text =null;
    Button button=null;
    String str=null;
    AnsyTry anys=null;
    double result=0;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        text=(TextView) findViewById(R.id.text);
        button=(Button) findViewById(R.id.button);
        str="wei";
        button.setOnClickListener(new OnClickListener() {
           
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                anys=new AnsyTry(text);
                anys.execute(str);
               
            }
        });
    }
   
   
    class AnsyTry extends AsyncTask<String, TextView, Double>{
       
        TextView te=null;
       
        public AnsyTry(TextView te) {
            super();
            this.te = te;
        }

        @Override
        protected Double doInBackground(String... params) {
            // TODO Auto-generated method stub
            double dou=0;
            if(params[0].equals("wei")){
                System.out.println(Thread.currentThread().getName()+"  recive wei");
                dou=100;
            }
            publishProgress(te);
            return dou;
        }

        @Override
        protected void onPostExecute(Double result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            System.out.println("postExecute---double---"+result);
        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub\
            System.out.println("pretExecute------");
            super.onPreExecute();
        }

        @Override
        protected void onProgressUpdate(TextView... values) {
            // TODO Auto-generated method stub
            values[0].setText(values[0].getText()+"1");
            super.onProgressUpdate(values);
        }
       
    }
}

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


android提供了一套專門用於異步處理的類。即:AynsTask類。使用這個類可以爲耗時程序開闢一個新線程進行處理,處理完時返回。
其實,AsynTask類就是對Thread類的一個封裝,並且加入了一些新的方法。編程時,兩者都可以實現同樣的功能。本文後面將對AsynTask和Thread進行比較。
1、AsynTask類結構
asysTask類主要用到的幾個內部回調函數有:
doInBackGround()

onPreExecute()

onPostExecute()

onProgressUpdate()
複製代碼
正是這幾個回調函數構成了AsynTask類的使用邏輯結構。
注意:每個AsynTask子類必須至少複寫doInBackGround()方法。
2、回調邏輯關係
調用關係如下圖:
    

 


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代碼:
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;

public class AnsyTestActivity extends Activity {
    /** Called when the activity is first created. */
   
    TextView text =null;
    Button button=null;
    String str=null;
    AnsyTry anys=null;
    double result=0;
   
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        text=(TextView) findViewById(R.id.text);
        button=(Button) findViewById(R.id.button);
        str="wei";
        button.setOnClickListener(new OnClickListener() {
           
            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                anys=new AnsyTry(text);
                anys.execute(str);
               
            }
        });
    }
   
   
    class AnsyTry extends AsyncTask<String, TextView, Double>{
       
        TextView te=null;
       
        public AnsyTry(TextView te) {
            super();
            this.te = te;
        }

        @Override
        protected Double doInBackground(String... params) {
            // TODO Auto-generated method stub
            double dou=0;
            if(params[0].equals("wei")){
                System.out.println(Thread.currentThread().getName()+"  recive wei");
                dou=100;
            }
            publishProgress(te);
            return dou;
        }

        @Override
        protected void onPostExecute(Double result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            System.out.println("postExecute---double---"+result);
        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub\
            System.out.println("pretExecute------");
            super.onPreExecute();
        }

        @Override
        protected void onProgressUpdate(TextView... values) {
            // TODO Auto-generated method stub
            values[0].setText(values[0].getText()+"1");
            super.onProgressUpdate(values);
        }
       
    }
}

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


發佈了7 篇原創文章 · 獲贊 0 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章