目錄
1. 定義
官方解釋:AsyncTask可以正確及方便地使用UI線程。此類允許您執行後臺操作並在UI線程上發佈結果,而無需通過操作Thread和Handler。AsyncTasks應該用於短操作(最多幾秒鐘)。異步任務在後臺線程運行計算,其結果在UI線程上發佈。
1.1 3個泛型參數介紹
java.lang.Object
↳ android.os.AsyncTask<Params, Progress, Result>
1. Params(傳入參數類型):execute() 執行時傳入給Task的參數。
2. Progress(執行進度類型):異步任務在後臺執行的進度單位類型。
3. Result(執行結果類型):後臺執行完異步任務計算返回的結果類型。
如果不執行,則Void類型,如:
private class MyTask extends AsyncTask<Void, Void, Void> { ... }
1.2 任務執行的4個步驟
1、onPreExecute():在UI線程中工作,在doInBackground()任務計算前執行
2、doInBackground(Params...):在線程池中工作,所以不可任何UI操作,在onPreExecute()執行結束後立即執行,用與執行長時間的計算工作(即耗時工作),Params參數是通過在主線程中調用execute()方法傳入。計算工作完成後就會將計算結果返回給onPostExecute(Result)方法。也可以通過調用publishProgress(Progress)方法將 執行進度 傳遞給onProgressUpdate(Progress)方法。
3、onProgressUpdate(Progress...):在UI線程中工作,會在doInBackground()中執行publishProgress()方法後執行,此方法用於在後臺計算仍在執行時(也就是doInBackgound()還在執行是)將計算執行進度通過UI顯示出來,方便用戶知道後臺任務執行的進度。
4、onPostExecute(Result):在UI線程中工作,在doInBackground()執行完將結果傳入過來後執行。
2. Demo例子
詳細代碼:
public class AsyncTaskActivity extends AppCompatActivity implements View.OnClickListener {
private ProgressBar progressBar;
private TextView displayTv;
private Button startBtn, stopBtn;
private MyAsyncTask myAsyncTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_async_task);
progressBar = findViewById(R.id.progress_bar);
displayTv = findViewById(R.id.display_tv);
startBtn = findViewById(R.id.start_btn);
stopBtn = findViewById(R.id.stop_btn);
myAsyncTask = new MyAsyncTask();
startBtn.setOnClickListener(this);
stopBtn.setOnClickListener(this);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.start_btn:
myAsyncTask.execute("Jere test");
//AsyncTask只能執行一次,如果你在AsyncTask執行過程中再次調用 execute() 執行它,就會跳IllegalStateException異常
//java.lang.IllegalStateException: Cannot execute task: the task is already running.
startBtn.setEnabled(false);
break;
case R.id.stop_btn:
//中斷線程執行
myAsyncTask.cancel(true);
break;
default:
break;
}
}
/**
* 創建MyAsyncTask類, 繼承AsyncTask類 -> AsyncTask<Params, Progress, Result>
* 3個泛型參數指定類型:
* Params(輸入參數): String類型
* Progress(執行進度): Integer類型
* Result(執行結果): String類型
*/
private class MyAsyncTask extends AsyncTask<String, Integer, String> {
/**
* 在後臺任務開始計算執行前執行onPreExecute()操作
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
displayTv.setText("onPreExecute: start! ");
Toast.makeText(AsyncTaskActivity.this, "onPreExecute", Toast.LENGTH_SHORT).show();
}
/**
* 接收輸入參數,執行後臺任務中的計算工作(耗時操作),計算結束,返回計算結果
* @param strings Params輸入參數,在主線程執行execute()傳入的參數
* @return 返回執行結果給onPostExecute()
*/
@Override
protected String doInBackground(String... strings) {
for (int i = 1; i <= 10; i++) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//通過調用publishProgress()方法,將執行進度傳遞給onProgressUpdate()
publishProgress(i);
}
String result;
result = Arrays.toString(strings) + " return from doInBackground";
return result;
}
/**
* 接收後臺計算執行進度,在UI線程中通過ProgressBar現實執行進度。
* @param values : 執行進度,通過publishProgress()傳入
*/
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
//得到一個整型數組,但每次裏面只有一個元素,所有通過values[0]就可以拿到當前的執行進度
progressBar.setProgress(values[0]);
displayTv.setText("onProgressUpdate: value = " + values[0]);
}
/**
* 接收後臺任務計算結束返回的結果,在UI線程上顯示出來
* @param s :後臺計算結束返回的執行結果,由doInBackground()返回
*/
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
displayTv.setText("onPostExecute: " + s);
Toast.makeText(AsyncTaskActivity.this, "onPostExecute", Toast.LENGTH_SHORT).show();
}
/**
* 在主線程中調用cancel()方法,執行onCancelled(),取消執行後臺任務
*
* 當任務計算完成時,無法取消任務,或者已經取消任務後不可再次取消
*/
@Override
protected void onCancelled() {
super.onCancelled();
displayTv.setText("onCancelled");
progressBar.setProgress(0);
Toast.makeText(AsyncTaskActivity.this, "onCancelled", Toast.LENGTH_SHORT).show();
}
}
}
額外中斷任務的效果如下:👇
具體代碼請看 👉 源代碼