android學習筆記——AsyncTask異步消息處理機制簡單介紹及使用

後續跟有筆者自己的代碼,大家可以拿去自己試一下

1、對於耗時的操作,我們的一般方法是開啓“子線程”。如果需要更新UI,則需要使用handler

2、如果耗時的操作太多,那麼我們需要開啓太多的子線程,這就會給系統帶來巨大的負擔,隨之也會帶來性能方面的問題。在這種情況下我們就可以考慮使用類AsyncTask來異步執行任務,不需要子線程和handler,就可以完成異步操作和刷新UI。

3、AsyncTask:對線程間的通訊做了包裝,是後臺線程和UI線程可以簡易通訊:後臺線程執行異步任務,將result告知UI線程。

4、使用方法:共分爲兩步,自定義AsyncTask,在耗時的地方調用自定義的AsyncTask。可以參照以下代碼示例。

step1:繼承AsyncTask<Params,Progress,Result>

           Params:輸入參數。對應的是調用自定義的AsyncTask的類中調用excute()方法中傳遞的參數。如果不需要傳遞參數,則直接設爲Void即可。

           Progress:子線程執行的百分比

           Result:返回值類型。和doInBackground()方法的返回值類型保持一致。

step2:實現以下幾個方法:執行時機和作用看示例代碼,以下對返回值類型和參數進行說明

          onPreExecute():無返回值類型。不傳參數

          doInBackground(Params... params):返回值類型和Result保持一致。參數:若無就傳遞Void;若有,就可用Params

          publishProgress(Params... params):在執行此方法的時候會直接調用onProgressUpdate(Params... values)

          onProgressUpdate(Params... values):無返回值類型。參數:若無就傳遞Void;若有,就可用Progress

          onPostExecute(Result  result) :無返回值類型。參數:和Result保持一致。

step3:在調用自定義的AsyncTask類中生成對象;

          執行  :對象.excute(Params... params);

小注:

   1) Task的實例必須在UI thread中創建

 

    2) execute方法必須在UI thread中調用

 

    3) 不要手動的調用onPreExecute(), onPostExecute(Result),doInBackground=\'#\'" onProgressUpdate(Progress...)這幾個方法

 

    4) 該task只能被執行一次,否則多次調用時將會出現異常

AsyncTask主要方法的梳理:

執行次序 執行時機 方法名稱 調用方
1 異步任務執行前 onPreExecute UI線程
2 異步任務執行中 doInBackground 後臺線程
3 異步任務執行中 publishProgress 後臺線程
4 異步任務執行中 onProgressUpdate UI線程
5 異步任務執行後 onPostExecute UI線程

示例代碼:
佈局layout1.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Hello"/>
    <Button
        android:id="@+id/download"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Download"/>
    <TextView
        android:id="@+id/tv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="當前進度顯示"/>
    <ProgressBar
        android:id="@+id/pb"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        style="?android:attr/progressBarStyleHorizontal"/>
</LinearLayout>

AsyncTaskDemoActivity.java
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;

public class AsyncTaskDemoActivity extends Activity {
    /** Called when the activity is first created. */
    private Button download;
    private TextView tv;
    private ProgressBar pb;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout1);

        initView();
    }
    private void initView() {
        // TODO Auto-generated method stub
        tv=(TextView)findViewById(R.id.tv);
        pb=(ProgressBar)findViewById(R.id.pb);
        download=(Button)findViewById(R.id.download);
        download.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                DownloadTask dt=new DownloadTask(AsyncTaskDemoActivity.this,pb,tv);
                dt.execute(100);//參數影響線程的休息時間
            }
        });
    }
}

DownloadAsyncTask.java
import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;
import android.widget.ProgressBar;
import android.widget.TextView;

public class DownloadAsyncTask extends AsyncTask<Integer, Integer, String> {
    //後面尖括號內分別是參數(線程休息時間),進度(publishProgress用到),返回值 類型 

    private Context mContext=null;
    private ProgressBar mProgressBar=null;
    private TextView mTextView=null;
    public DownloadAsyncTask(Context context, ProgressBar pb, TextView tv){
        this.mContext=context;
        this.mProgressBar=pb;
        this.mTextView=tv;
    }
    /*
     * 第一個執行的方法
     * 執行時機:在執行實際的後臺操作前,被UI 線程調用
     * 作用:可以在該方法中做一些準備工作,如在界面上顯示一個進度條,或者一些控件的實例化,這個方法可以不用實現。
     * @see android.os.AsyncTask#onPreExecute()
     */
    @Override
    protected void onPreExecute() {
        // TODO Auto-generated method stub
        Log.d("DownloadAsyncTask""onPreExecute executed");
        super.onPreExecute();
    }

    /*
     * 執行時機:在onPreExecute 方法執行後馬上執行,該方法運行在後臺線程中
     * 作用:主要負責執行那些很耗時的後臺處理工作。可以調用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。
     * @see android.os.AsyncTask#doInBackground(Params[])
     */
    @Override
    protected String doInBackground(Integer... params) {
        // TODO Auto-generated method stub
        Log.d("DownloadAsyncTask""doInBackground executed");
        for(int i=0;i<=100;i++){
            publishProgress(i);//當前任務進度通過i傳入
            try {
                Thread.sleep(params[0]);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return "執行完畢";
    }

    /*
     * 執行時機:這個函數在doInBackground調用publishProgress時被調用後,UI 線程將調用這個方法.雖然此方法只有一個參數,但此參數是一個數組,可以用values[i]來調用
     * 作用:在界面上展示任務的進展情況,例如通過一個進度條進行展示。此實例中,該方法會被執行100次
     * @see android.os.AsyncTask#onProgressUpdate(Progress[])
     */
    @Override
    protected void onProgressUpdate(Integer... values) {
        int progress = values[0];
        // TODO Auto-generated method stub
        Log.d("DownloadAsyncTask""onProgressUpdate executed");
        mProgressBar.setProgress(progress);
        mTextView.setText(values[0]+"%");
        super.onProgressUpdate(values);
    }

    /*
     * 執行時機:在doInBackground 執行完成後,將被UI 線程調用
     * 作用:後臺的計算結果將通過該方法傳遞到UI 線程,並且在界面上展示給用戶
     * result:上面doInBackground執行後的返回值,所以這裏是"執行完畢" 
     * @see android.os.AsyncTask#onPostExecute(java.lang.Object)
     */
    @Override
    protected void onPostExecute(String result) {
        // TODO Auto-generated method stub
        Log.d("DownloadAsyncTask""onPostExecute executed");

        super.onPostExecute(result);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章