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);
小注:
示例代碼:
<?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