參考瘋狂Android講義3.6章:
AsyncTask<Params,Progress,Result> 抽象類,三個泛型參數:
Params:啓動任務執行的輸入參數類型;
Progress:後臺任務完成的進度值的類型;
Result:後臺任務執行後返回的結果類型;
不需要指定類型的話用Void。
必須要繼承重寫的方法是:
doInBackground(Params... param):後臺線程要完成的任務;可以在該方法中調用publishProgress(Progress... values)方法更新任務執行的進度。
下邊例子還用到的方法:
onProgressUpdate(Progress... values):如果在doInBackground方法中調用publishProgress方法,則會觸發該方法;
onPreExecute():在執行後臺任務之前調用該方法,通常執行一些初始化工作,如在界面上顯示進度條;
onPostExecute(Result result):doInBackground方法執行完後將執行該方法,並將返回值作爲參數傳入該方法;
調用AsyncTask對象時,必須在UI線程中實例化對象,然後執行execute方法,開始後臺任務。
注意事項:
上邊提到的4個方法,都應該由Android系統負責調用。程序員只能調用實例對象的execute方法。
另外execute方法只能被執行一次,多次調用會報錯:
E/AndroidRuntime(3226): Caused by: java.lang.IllegalStateException: Cannot execute task: the task is already running.
crazy Android 給的示例:
package org.crazyit.handler;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
/**
* Description: <br/>
* site: <a href="http://www.crazyit.org">crazyit.org</a> <br/>
* Copyright (C), 2001-2014, Yeeku.H.Lee <br/>
* This program is protected by copyright laws. <br/>
* Program Name: <br/>
* Date:
* @author Yeeku.H.Lee [email protected]
* @version 1.0
*/
public class AsyncTaskTest extends Activity
{
private TextView show;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
show = (TextView) findViewById(R.id.show);
}
// 重寫該方法,爲界面的按鈕提供事件響應方法
public void download(View source) throws MalformedURLException
{
DownTask task = new DownTask(this);
task.execute(new URL("http://www.so.cn"));
}
class DownTask extends AsyncTask<URL, Integer, String>
{
// 可變長的輸入參數,與AsyncTask.exucute()對應
ProgressDialog pdialog;
// 定義記錄已經讀取行的數量
int hasRead = 0;
Context mContext;
public DownTask(Context ctx)
{
mContext = ctx;
}
@Override
protected String doInBackground(URL... params)
{
StringBuilder sb = new StringBuilder();
try
{
URLConnection conn = params[0].openConnection();
// 打開conn連接對應的輸入流,並將它包裝成BufferedReader
BufferedReader br = new BufferedReader(
new InputStreamReader(conn.getInputStream()
, "utf-8"));
String line = null;
while ((line = br.readLine()) != null)
{
sb.append(line + "\n");
hasRead++;
publishProgress(hasRead);
}
return sb.toString();
}
catch (Exception e)
{
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(String result)
{
// 返回HTML頁面的內容
show.setText(result);
pdialog.dismiss();
}
@Override
protected void onPreExecute()
{
pdialog = new ProgressDialog(mContext);
// 設置對話框的標題
pdialog.setTitle("任務正在執行中");
// 設置對話框 顯示的內容
pdialog.setMessage("任務正在執行中,敬請等待...");
// 設置對話框不能用“取消”按鈕關閉
pdialog.setCancelable(true);
// 設置該進度條的最大進度值
pdialog.setMax(100);
// 設置對話框的進度條風格
pdialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
// 設置對話框的進度條是否顯示進度
pdialog.setIndeterminate(true);
pdialog.show();
}
@Override
protected void onProgressUpdate(Integer... values)
{
// 更新進度
show.setText("已經讀取了【" + values[0] + "】行!");
pdialog.setProgress(values[0]);
}
}
}
值得注意的是AndroidManifest.xml文件中需要加上訪問Internet URL的權限:
<uses-permission android:name="android.permission.INTERNET"/>
More about AsyncTask:
Android3.0之前,異步任務的線程池介紹:
http://www.linuxidc.com/Linux/2011-09/43150.htm
1、線程池中的工作線程少於5個時,將會創建新的工作線程執行異步任務
2、線程池中已經有5個線程,緩衝隊列未滿,異步任務將會放到緩衝隊列中等待
3、線程池中已經有5個線程,緩衝隊列已滿,那麼線程池將新開工作線程執行異步任務
4、線程池中已經有128個線程,緩衝隊列已滿,如果此時向線程提交任務,將會拋出RejectedExecutionException
5個以內的線程可以同步進行,6-15會放入緩衝隊列,16-128以上會新開啓新的工作線程。128以上會拋出異常。
3.0之後的異步任務線程池添加了新增了接口#executeOnExecutor(),可以自定義線程池。新增了二個預定義的線程池SERIAL_EXECUTOR和THREAD_POOL_EXECUTOR。
1、executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR)就跟2.3版本的AsyncTask.execute()效果是一樣的
2、默認AsyncTask.execute()會一個接一個任務進行,不會同時進行,也就是SERIAL_EXECUTOR
3、如果你想讓所有的任務都能併發同時運行,那就創建一個沒有限制的線程池(Executors.newCachedThreadPool())
http://blog.csdn.net/hitlion2008/article/details/7983449