五十、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只能被執行一次,否則多次調用時將會出現異常

 

示例代碼:

 

<?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 , Welcome to Andy's Blog!"/>  
    <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>

 

package sn.demo;

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

public class DownloadTask extends AsyncTask<Integer, Integer, String> {
    //后面尖括號內分別是參數(線程休息時間),進度(publishProgress用到),返回值 類型  
    
    private Context mContext=null;
    private ProgressBar mProgressBar=null;
    private TextView mTextView=null;
    public DownloadTask(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("sn", "00000");
        super.onPreExecute();
    }
    
    /*
     * 執行時機:在onPreExecute 方法執行后馬上執行,該方法運行在后台線程中
     * 作用:主要負責執行那些很耗時的后台處理工作。可以調用 publishProgress方法來更新實時的任務進度。該方法是抽象方法,子類必須實現。
     * @see android.os.AsyncTask#doInBackground(Params[])
     */
    @Override
    protected String doInBackground(Integer... params) {
        // TODO Auto-generated method stub
        Log.d("sn", "1111111");
        for(int i=0;i<=100;i++){
            mProgressBar.setProgress(i);
            publishProgress(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) {
        // TODO Auto-generated method stub
        Log.d("sn", "2222222222");
        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("sn", "3333333333");
        
        super.onPostExecute(result);
    }




}
package sn.demo;

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.main);
        
        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);
            }
        });
    }
}

 

 

參照連接

http://blog.csdn.net/cjjky/article/details/6684959

http://blog.csdn.net/zhenyongyuan123/article/details/5850389

http://www.eoeandroid.com/thread-102664-1-1.html


免責聲明!

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



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