Android中如何巧妙停止執行緒的方法
阿新 • • 發佈:2019-01-09
好長時間沒更新部落格了,最近聽取別人的部落格寫作經驗,將開發中遇到的問題進行分享也是原創。這是去年的網約車專案中遇到的。
在處理多執行緒任務時,比如倒計時接單(通過子執行緒實現倒計時),新來訂單15s後自動消失。而業務需求中又要允許使用者在倒計時未結束時手動劃掉消失,則此時需要停止倒計時執行緒。或者可能有時有多單依次疊加,此時最上面的一單消失時,也需要先停止上一單倒計時再自動開啟下一單的倒計時。
如果是new Thread方式的interrupt()方法來停止執行緒,你列印時輸出會發現倒計時中累加的變數並未停止累加。箇中原因參看停止Java執行緒,小心interrupt()方法
萬般無奈中想起AsyncTask不是自帶執行緒停止方法麼,即taskProgress.cancel(true)(taskProgress是TaskProgress繼承AsyncTask後新new的物件),並且自帶判斷執行緒是否正在執行的方法taskProgress.getStatus() == AsyncTask.Status.RUNNING,果斷解決問題。程式碼如下:
/*
* 新來訂單時開始計時
*/
public static TaskProgress taskProgress;
public void startCountdown(final int mProgress, final int maxtime) {
if (maxtime > 0) {
roundProgressBar.setVisibility(View.VISIBLE);
if (taskProgress != null && taskProgress.getStatus() == AsyncTask.Status.RUNNING)
{
taskProgress.cancel(true ); // 如果Task還在執行,則先取消它,然後執行關閉activity程式碼
taskProgress = null;
}
taskProgress = new TaskProgress(maxtime);
taskProgress.execute(0);
}
}
/*
* 開啟倒計時,倒計時任務需要能手動停止,故而用AsyncTask,Thread無法在左右滑動卡片時停止執行緒
*/
public class TaskProgress extends AsyncTask<Integer, Integer, Integer> {// 繼承AsyncTask
int maxtime;
int mProgress;
public TaskProgress(int maxtime) {
this.maxtime = maxtime;
}
@Override
protected Integer doInBackground(Integer... params) {// 處理後臺執行的任務,在後臺執行緒執行
int flag = 1;
if (isCancelled())
return null;
mProgress = params[0];
while (mProgress <= maxtime && !isCancelled()) {
try {
publishProgress(mProgress);//將會呼叫onProgressUpdate(Integer... progress)方法
mProgress += 1;
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
LogUtils.e("-----------------------", String.valueOf(mProgress));
LogUtils.e("-----------------------", String.valueOf(mProgress));
LogUtils.e("-----------------------", String.valueOf(mProgress));
}
return flag;
}
protected void onProgressUpdate(Integer... progress) {// 在呼叫publishProgress之後被呼叫,在ui執行緒執行
// roundProgressBar.setProgress(progress[0]);//更新進度條的進度
if (isCancelled()) {
return;
} else {
roundProgressBar.setProgress(progress[0], maxtime);
}
}
protected void onPostExecute(Integer result) {// 後臺任務執行完之後被呼叫,在ui執行緒執行
if (result != null) {
//自動消失
MainActivity.getInstance().vanishOnDisappear();
}
}
protected void onPreExecute() {// 在doInBackground(Params...)之前被呼叫,在ui執行緒執行
roundProgressBar.setProgress(0, maxtime);// 進度條復位
}
protected void onCancelled() {// 在ui執行緒執行
// roundProgressBar.setProgress(0, maxtime);// 進度條復位
}
}
剩下的問題時,為什麼這個非同步任務的執行緒可以通過cancel方法停止呢?未完待續……..因為我還沒看原始碼深究@[email protected]。