AsyncTask基本用法
一、AsyncTask的基本用法
- 要使用AsyncTask首先的創(chuàng)建一個(gè)繼承自AsyncTask抽象類的類,看一下ProgressAsyncTask.java的實(shí)現(xiàn):
public class ProgressAsyncTask extends AsyncTask<Context, Integer, Void> {
private MainActivity mMainActivity;
/**
* 后臺(tái)任務(wù)開始執(zhí)行之間調(diào)用,用于進(jìn)行一些界面上的初始化操作,例如:
* 設(shè)置進(jìn)度條可見、初始化數(shù)據(jù)
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected Void doInBackground(Context... contexts) {
mMainActivity = (MainActivity) contexts[0];
for (int i=0;i<100;i++){
if (this.isCancelled() == true){
break;
}
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
publishProgress(i);
}
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
if (isCancelled()){
return;
}
mMainActivity.setmProgress(values[0]);
}
}
創(chuàng)建這個(gè)類的時(shí)候需要指定三個(gè)泛型參數(shù),看一下這三個(gè)參數(shù)的意義:
- Paramas:在執(zhí)行AsyncTask時(shí)需要傳入的參數(shù),可用于在后臺(tái)任務(wù)中使用。
- Progress:后臺(tái)執(zhí)行耗時(shí)任務(wù)時(shí),返回的任務(wù)進(jìn)度
- Result:任務(wù)執(zhí)行完畢后返回的結(jié)果
三個(gè)參數(shù)的傳遞規(guī)則:
- 第一個(gè)Paramas,是在執(zhí)行mAsyncTask.execute()這個(gè)方法
傳進(jìn)去的參數(shù) - 第二個(gè)Progress,在doInBackground()這個(gè)方法中調(diào)用publishProgress(i)傳進(jìn)去的參數(shù)i,
最終會(huì)在onProgressUpdate()這個(gè)方法中收到 - 第三個(gè)參數(shù)Result,doInBackground()這個(gè)方法最終返回的
參數(shù),會(huì)在onPostExecute()這個(gè)方法中收到
然后這里說(shuō)一下上面幾個(gè)方法是執(zhí)行先后順序:
- onPreExecute():后臺(tái)任務(wù)開始之前執(zhí)行,主要是做一些初始化操作
- doInBackground():這個(gè)線程的方法在子線程執(zhí)行,耗時(shí)操作都在這里執(zhí)行,第一個(gè)參數(shù)Paramas會(huì)傳到這個(gè)方法,然后這個(gè)方法的返回值會(huì)作為參數(shù)傳到onPostExecute()這個(gè)方法。在這個(gè)方法中調(diào)用publishProgress(),還會(huì)執(zhí)行onProgressUpdate(Progress...)這個(gè)方法,
- onProgressUpdate(Progress...):這個(gè)方法主要用來(lái)更新耗時(shí)任務(wù)的進(jìn)度等
- onPostExecute(Result):耗時(shí)任務(wù)執(zhí)行完成執(zhí)行這個(gè)方法,會(huì)接收耗時(shí)任務(wù)的返回值。常根據(jù)返回的數(shù)據(jù)做一些UI上的操作:例如提示下載完成、關(guān)閉進(jìn)度條對(duì)話框
然后看一下Activity中的調(diào)用:
public class MainActivity extends AppCompatActivity {
private Button mProgressBtn;
private ProgressBar mProgressBar;
private ProgressAsyncTask mAsyncTask;
public ProgressBar getmProgressBar() {
return mProgressBar;
}
public void setmProgress(Integer progress) {
mProgressBar.setProgress(progress);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mAsyncTask = new ProgressAsyncTask();
mProgressBtn = (Button) findViewById(R.id.button_progress);
mProgressBar = (ProgressBar) findViewById(R.id.progressbar_async);
mProgressBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mAsyncTask.execute(MainActivity.this);
}
});
}
@Override
protected void onDestroy() {
super.onDestroy();
/**
* 1、綁定AsyncTask的生命周期與Activity相同
* 2、cancel方法只是將對(duì)應(yīng)的AsyncTask標(biāo)記為cacel狀態(tài),并不是真正的取消線程的執(zhí)行
* 3、然后我們需要在onPostExecute方法、onProgressUpdate方法、doInBackground方法做判斷,如果是cancel
* 狀態(tài)怎么辦
*/
if (mAsyncTask != null && mAsyncTask.getStatus() == AsyncTask.Status.RUNNING) {
mAsyncTask.cancel(true);
}
}
}
可以看到只需要執(zhí)行一句mAsyncTask.execute(MainActivity.this);就可以開啟這個(gè)異步任務(wù)了。
要想很好的使用AsyncTask可能需要把AsyncTask的生命周期與對(duì)應(yīng)的Activity的生命周期綁定。可以看到在Activity的onDestroy()方法中對(duì)這個(gè)AsyncTask進(jìn)行了cancel操作。此時(shí)只是把這個(gè)異步任務(wù)cancel了,而不是真正的暫停了。然后在AsyncTask的方法中進(jìn)行判斷如果當(dāng)前狀態(tài)是一個(gè)cancel狀態(tài),那就不進(jìn)行耗時(shí)操作和UI界面的刷新。
還有一個(gè)疑問(wèn):這個(gè)子線程什么時(shí)候關(guān)閉?如果異步任務(wù)執(zhí)行mAsyncTask.cancel(true);這個(gè)操作,那這個(gè)異步任務(wù)什么時(shí)候停止?